美文网首页
Django学习-- unique_together处理含有NU

Django学习-- unique_together处理含有NU

作者: alue | 来源:发表于2019-03-09 09:31 被阅读0次

有如下人员类型模型:

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')

此时, 如果提交两个数据, 它们 departmenttype相同, 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管理页面, 就可以正常抛出重复提示了.

此时,unique_together起作用了

相关文章

网友评论

      本文标题:Django学习-- unique_together处理含有NU

      本文链接:https://www.haomeiwen.com/subject/ssojpqtx.html