有如下人员类型模型:
class StudentType(models.Model):
class Meta:
# major字段,带有null, 这里的unique_together就不起作用了, 因为数据库中NULL不等于NULL
unique_together = [('department', 'major', 'type'),]
department = models.ForeignKey(Department,related_name='students',on_delete=models.CASCADE,verbose_name='单位')
major = models.CharField(verbose_name='专业名称',max_length=20,blank=True,null=True)
type = models.ForeignKey(StudentChoice, verbose_name='人员类型', on_delete=models.DO_NOTHING,related_name='students')
此时, 如果提交两个数据, 它们 department
和type
相同, major
都是null
, 那么django自身不会提示'唯一性错误', 因为数据库中NULL和NULL也是不相等的.
那么怎么优雅的处理这个问题呢? 在stackoverflow上, 找到了一个比较好的方法. 搬运如下:
from django.core.exceptions import ValidationError
class StudentType(models.Model):
class Meta:
unique_together = [('department', 'major', 'type'),]
# 通过重写validate_unique, 自定义错误处理
def validate_unique(self, exclude=None):
if StudentType.objects.exclude(id=self.id).filter(department=self.department, \
major__isnull=True,type=self.type).exists():
raise ValidationError("该人员类型已经存在!")
super(StudentType, self).validate_unique(exclude)
department = models.ForeignKey(Department,related_name='students',on_delete=models.CASCADE,verbose_name='单位')
major = models.CharField(verbose_name='专业名称',max_length=20,blank=True,null=True)
type = models.ForeignKey(StudentChoice, verbose_name='人员类型', on_delete=models.DO_NOTHING,related_name='students')
这样, 在后台admin管理页面, 就可以正常抛出重复提示了.

网友评论