Django model filter with validate_unique()

在 Django 中使用 validate_unique() 方法时,遇到 “invalid syntax” 的错误。

代码如下:

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    is_joined = models.BooleanField(default=False)  # if True, joined, else wish_member
    is_master = models.BooleanField(default=False)

    def __str__(self):
        if (self.is_joined):
            return self.person.name + " is a member in Group " + self.group.name
        return self.person.name + " wishes to join in Group " + self.group.name

    def validate_unique(self, *args, **kwargs):
        # super(Person, self.person).validate_unique(*args, **kwargs)
        # tests if there is already the same person in the same group.
        if (self.__class__.objects.filter(person_id=self.person.id, group_id=self.group.id,).exists()):
            raise ValidationError(
                {
                    NON_FIELD_ERRORS:
                        ('The person already exists.',)
                }
            )
        elif (self.__class__objects.filter(is_master=True, group_id=self.group.id,).exists()):
            raise ValidationError(
                {
                    NON_FIELD_ERRORS:
                        ('The master already exists.')
                })

# Edits: noticed the dot missing.leaving it there for the credit who found it.
# Error occurs in:
# elif(self.__class__.objects.filter(is_master = True, group_id = self.group.id,).exists()):

2. 解决方案:

1. 语法错误

validate_unique() 方法中,elif (self.__class__objects.filter(is_master=True, group_id=self.group.id,).exists()): 这行代码中,__class__objects 写成了 __class__.objects

正确的代码如下:

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    is_joined = models.BooleanField(default=False)  # if True, joined, else wish_member
    is_master = models.BooleanField(default=False)

    def __str__(self):
        if (self.is_joined):
            return self.person.name + " is a member in Group " + self.group.name
        return self.person.name + " wishes to join in Group " + self.group.name

    def validate_unique(self, *args, **kwargs):
        # super(Person, self.person).validate_unique(*args, **kwargs)
        # tests if there is already the same person in the same group.
        if (self.__class__.objects.filter(person_id=self.person.id, group_id=self.group.id,).exists()):
            raise ValidationError(
                {
                    NON_FIELD_ERRORS:
                        ('The person already exists.',)
                }
            )
        elif (self.__class__.objects.filter(is_master=True, group_id=self.group.id,).exists()):
            raise ValidationError(
                {
                    NON_FIELD_ERRORS:
                        ('The master already exists.')
                })

2. 使用 unique_together

也可以使用 unique_together 选项来实现类似的功能。

Membership 模型中添加如下代码:

class Meta:
    unique_together = (
        ("person", "group"),
        ("is_master", "group"),
    )

这样,persongroup 的组合以及 is_mastergroup 的组合都将是唯一的。

3. 自定义 validate_unique() 方法

还可以自定义 validate_unique() 方法来实现类似的功能。

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    is_joined = models.BooleanField(default=False)  # if True, joined, else wish_member
    is_master = models.BooleanField(default=False)

    def __str__(self):
        if (self.is_joined):
            return self.person.name + " is a member in Group " + self.group.name
        return self.person.name + " wishes to join in Group " + self.group.name

    def validate_unique(self, *args, **kwargs):
        # Check if the person is already a member of the group
        if self.__class__.objects.filter(person=self.person, group=self.group).exists():
            raise ValidationError(
                {
                    NON_FIELD_ERRORS:
                        ('The person is already a member of the group.')
                }
            )

        # Check if there is already a master for the group
        if self.__class__.objects.filter(is_master=True, group=self.group).exists():
            raise ValidationError(
                {
                    NON_FIELD_ERRORS:
                        ('There is already a master for the group.')
                }
            )

这样,也可以实现 persongroup 的组合以及 is_mastergroup 的组合都是唯一的。

根据你的具体需求,可以选择其中一种方法来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值