首页 > 解决方案 > 使用户电子邮件唯一 django

问题描述

用户注册时,如何使 Django 用户电子邮件独一无二?

表格.py

class SignUpForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")

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

我正在使用来自 django.contrib.auth.models 的用户。我是否需要覆盖模型中的用户。目前该模型不引用用户。

视图.py

class SignUp(generic.CreateView):
    form_class = SignUpForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

标签: pythondjango

解决方案


最好的答案是使用CustomUser子类AbstractUser并将唯一的电子邮件地址放在那里。例如:

from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)

并使用 更新设置AUTH_USER_MODEL="app.CustomUser"

但是,如果您不需要将唯一的电子邮件存储在数据库中或者可能不将其用作用户名字段,那么您可以更新表单的clean方法以进行验证。例如:

from django.core.exceptions import ValidationError


class YourForm(UserCreationForm):

    def clean(self):
       email = self.cleaned_data.get('email')
       if User.objects.filter(email=email).exists():
            raise ValidationError("Email exists")
       return self.cleaned_data

更新

如果您处于项目中期,那么您可以按照有关如何更改迁移的文档进行操作,简而言之:

  1. 备份你的数据库
  2. 创建一个与 auth.User 相同的自定义用户模型,将其命名为 User(如此多对多的表保持相同的名称)并设置 db_table='auth_user'(因此它使用同一个表)
  3. 删除所有迁移文件(除了__init__.py
  4. 从表中删除所有条目django_migrations
  5. 使用创建所有迁移文件python manage.py makemigrations
  6. 运行假迁移python manage.py migrate --fake
  7. 取消db_table设置,对自定义模型进行其他更改,生成迁移,应用它们

但是如果你刚刚开始,那么删除迁移目录中的数据库和迁移文件,除了__init__.py. 然后创建一个新数据库,创建新的迁移集python manage.py makemigrations并应用迁移python manage.py migrate

对于其他模型中的参考,您可以参考它们settings.AUTH_USER_MODEL以避免将来出现任何问题。例如:

user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)

它将自动引用当前的用户模型。


推荐阅读