Django Unique Field为无值引发错误

时间:2017-05-25 22:01:57

标签: python django django-models model unique

我在尝试创建没有电子邮件的第二个用户时收到duplicate key value violates unique constraint "users_user_email_key" DETAIL: Key (email)=(None) already exists.错误。

电子邮件字段定义:

email = models.EmailField(verbose_name='email address', max_length=255, unique=True, null = True, blank = True)

从创建用户的表单:

def clean_email(self):
    email = self.cleaned_data.get('email')
    if email:
        if email == "":
            return None
        else:
            return email
    else:
        return None

我在这里做错了什么?所有的意见都表示赞赏,谢谢!

2 个答案:

答案 0 :(得分:0)

这是一个非常好的信息。您有一个对其具有唯一约束的字段,并且您允许它为null。如果您有一个空值电子邮件,则无法使用另一个,因为这会违反您的唯一约束。

你应该在这里考虑设计。如果您允许用户在没有电子邮件地址的系统中,则需要删除唯一约束。另一种选择是创建一个唯一的复合键,将电子邮件与非空字段组合在一起,但对于电子邮件(或更多字段,如果需要)将是唯一的。然而,您可能会通过这样做来开始混淆业务需求。如果您不关心数据完整性或有效性,您还可以插入随机ID或sequence.next_val作为电子邮件地址,但此时您会变得非常脏。

这里最简单的设计和最强的完整性不仅要求电子邮件地址,还要确认它是有效的电子邮件地址或至少是电子邮件地址格式。您保留唯一约束但不允许空值,并为提供的值添加一些前端和后端支持。

答案 1 :(得分:0)

如果将空字符串从None转换为表单的save方法,它将按您的描述工作。例如:

def save(self, commit=True):
    if self.instance.email == '':
        self.instance.email = None
    return super().save(commit)

这是我发现的转换唯一(如果存在)但可选的char字段的最干净的方法。