我有模特
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”
我该怎么做?在哪种验证方法中,我可以轻松地检查这个?
谢谢
答案 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)