私信  •  关注

Arne Babenhauserheide

Arne Babenhauserheide 最近创建的主题
Arne Babenhauserheide 最近回复了
7 年前
回复了 Arne Babenhauserheide 创建的主题 » 如何使电子邮件字段在Django的contrib.auth模型用户中唯一

警告: 下面的代码是为老版本的django编写的(之前 Custom User Models 介绍)。它包含一个竞赛条件,并且 只应与事务隔离级别一起使用 SERIALIZABLE 并请求范围内的事务。

因为字段实例的属性是只读的,所以代码无法工作。恐怕比你想象的要复杂一点。

如果只使用表单创建用户实例,则可以定义强制执行此行为的自定义模型表单:

from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User

    def clean_email(self):
        email = self.cleaned_data.get('email')
        username = self.cleaned_data.get('username')
        if email and User.objects.filter(email=email).exclude(username=username).exists():
            raise forms.ValidationError(u'Email addresses must be unique.')
        return email

然后只要在需要创建新用户的任何地方使用此表单。

顺便说一句,你可以用 Model._meta.get_field('field_name') 按名称而不是按位置获取字段。例如:

# The following lines are equivalent
User._meta.fields[4]
User._meta.get_field('email')

更新

Django文档建议您使用 clean 用于跨多个窗体字段的所有验证的方法,因为在 <FIELD>.clean <FIELD>_clean 方法。这意味着您可以(主要)依赖字段的值 cleaned_data 从内 清洁的 .

因为表单域是按照声明的顺序进行验证的,所以我认为偶尔可以将多字段验证放在 <现场清洁 方法,只要相关字段出现在它所依赖的所有其他字段之后。我这样做是为了使任何验证错误都与字段本身相关,而不是与表单相关。