Django auth.user 使用唯一邮箱

10 投票
7 回答
12720 浏览
提问于 2025-04-16 16:21

我在使用django.auth系统,遇到了这个问题:

class RegisterForm(UserCreationForm):
    username = forms.RegexField(label= "Username" , max_length = 30, regex = r'^[\w]+$', error_messages = {'invalid': "This value may contain only letters, numbers and _ characters."})
    email = forms.EmailField(label = "Email")
    first_name = forms.CharField(label = "First name", required = False)
    last_name = forms.CharField(label = "Last name", required = False)

    class Meta:
        model = User
        fields = ("username", "first_name", "last_name", "email", )

    def save(self, commit = True):
        user = super(RegisterForm, self).save(commit = False)
        user.first_name = self.cleaned_data["first_name"]
        user.last_name = self.cleaned_data["last_name"]
        user.email = self.cleaned_data["email"]
        if commit:
            user.save()
        return user

我想把邮箱设置为唯一的,并且在表单中检查这个验证。该怎么做呢?

7 个回答

1

我不太确定怎么用这个,不过

from django.contrib.auth.models import User
User._meta.get_field_by_name('email')[0].unique=True

应该可以做到。我想这个代码应该放在你的 models.py 文件里,然后在你对认证模型运行 syncdb 之前使用。我要自己试试看。

24

在你的模型中的某个地方:

from django.contrib.auth.models import User
User._meta.get_field('email')._unique = True

注意在 unique 前面的下划线。这是实际存储信息的地方。User._meta.get_field('email').unique 只是一个 @property,它会去查看这个信息。

这对于同步数据库也应该有效,所以你和数据库之间的数据会保持一致。

另外,从 Django 1.5 开始,你就不需要做这些事情了,因为用户模型会变得更加灵活。

10

把这个加到你的表单里。不过,这并不是最好的方法。仅仅使用这个表单的话,可能会出现竞争条件。建议你在数据库层面加上唯一性约束。

def clean_email(self):
    data = self.cleaned_data['email']
    if User.objects.filter(email=data).exists():
        raise forms.ValidationError("This email already used")
    return data

添加唯一性约束的SQL语句:

ALTER TABLE auth_user ADD UNIQUE (email)

撰写回答