Sử dụng cách tiếp cận tương tự như Sau-lơ, nhưng mục đích hơi khác:
class TrueUniqueBooleanField(BooleanField):
def __init__(self, unique_for=None, *args, **kwargs):
self.unique_for = unique_for
super(BooleanField, self).__init__(*args, **kwargs)
def pre_save(self, model_instance, add):
value = super(TrueUniqueBooleanField, self).pre_save(model_instance, add)
objects = model_instance.__class__.objects
if self.unique_for:
objects = objects.filter(**{self.unique_for: getattr(model_instance, self.unique_for)})
if value and objects.exclude(id=model_instance.id).filter(**{self.attname: True}):
msg = 'Only one instance of {} can have its field {} set to True'.format(model_instance.__class__, self.attname)
if self.unique_for:
msg += ' for each different {}'.format(self.unique_for)
raise ValidationError(msg)
return value
Việc triển khai này sẽ tăng một ValidationError
khi cố gắng lưu một bản ghi khác với giá trị True.
Ngoài ra, tôi đã thêm unique_for
đối số có thể được đặt thành bất kỳ trường nào khác trong mô hình, để chỉ kiểm tra tính duy nhất đúng cho các bản ghi có cùng giá trị, chẳng hạn như:
class Phone(models.Model):
user = models.ForeignKey(User)
main = TrueUniqueBooleanField(unique_for='user', default=False)