Django模型booleanfield仅适用于表1

时间:2016-02-06 13:03:55

标签: django

我有模特

class Owner(models.Model):
    name = models.CharField(max_length=10)

class PhoneNumber(models.Model):
    isActive = model.BooleanField(default=False)
    owner = model.ForeignKey('Owner')

我想强制只有一个PhoneNumber处于活动状态,因此如果用户在创建或编辑“非活动”PhoneNumber时,意外将其设置为“活动”并且还有另一个“活动”PhoneNumber,则表单不应提交并且会显示一个明确的错误,将'active'字段更改为False,错误文本“请在分配新的活动PhoneNumber之前停用旧的活动PhoneNumber”

我该怎么做?在哪种验证方法中,我可以轻松地检查这个?

谢谢

4 个答案:

答案 0 :(得分:1)

class Owner(models.Model):
    name = models.CharField(max_length=10)

class PhoneNumber(models.Model):
    isActive = models.NullBooleanField(default=None, unique=True)
    owner = model.ForeignKey('Owner')

    def save(self, *args, **kwargs):
        if self.isActive is False:
            self.isActive = None
        super(PhoneNumber, self).save(*args, **kwargs)

答案 1 :(得分:0)

这样的验证通常可以通过在模型的Meta类中定义unique_together来自动完成,但是这里不会起作用,因为每个用户可能有很多非活动的电话号码。所以你需要自定义验证。一种方法是在模型本身的clean方法中,在验证表单时调用它。

def clean(self):
    if self.isActive:
        active = PhoneNumber.objects.filter(isActive=True, owner=self.owner)
        if self.pk:
            active = active.exclude(pk=self.pk)
        if active.exists():
            raise ValidationError("An active phone number already exists for this user")

答案 2 :(得分:0)

没有一种方法可以做到这一点。但我可以建议在模型本身中执行此操作并覆盖save方法,如下所示:

class PhoneNumber(models.Model):
    isActive = model.BooleanField(default=False)
    owner = models.ForeignKey('Owner')
    phone_number = odels.CharField(max_length=50)

     class Meta:
        unique_together = ('user', 'phone_number',)

     def save(self, *args, **kwargs):
        if self.id: # to ensure that the object is being updated and is not a new one
             if not self.isActive:
                  check_active_uniquniess = self._meta.model.objects.filter(user = self.user).exclude(id=self.id).count()
                  if check_active_uniquniess:
                         raise ValidationError("Please deactivate the old active PhoneNumber before assigning a new active PhoneNumber")
        super(PhoneNumber, self).save(*args, **kwargs)

我还可以建议覆盖ModelForm中的clean方法。

答案 3 :(得分:0)

class Owner(models.Model):
    name = models.CharField(max_length=10)

class PhoneNumber(models.Model):
    phone_number = model.CharField(max_length=255)
    owner = model.ForeignKey('Owner')

class ActivePhoneNumber(models.Model):

    active_phone_number = model.ForeignKey(PhoneNumber)
    owner = model.OneToOneField(Owner)

PhoneNumber可以为每个所有者保留多个号码,其中ActivePhoneNumber每个所有者只有一个号码。这将在模型级别中强制执行每个用户规则的一个活动数字。

您仍需要提供表格来替换有效号码。类似的东西:

owner=self.request.user
new_number = PhoneNumber(owner=owner,phone_number="foobar")
# or new_number = owner.phone_number_set.get(phone_number="foobar")
new_number.save()
owner.active_phone_number.delete()
new_active = ActivePhoneNumber(owner=owner,active_phone_number=new_number)
new_active.save()

注意:如果一个所有者只能使用一个PhoneNumber,则设置:

active_phone_number = model.OneToOneField(PhoneNumber)