Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用户电子邮件成为唯一的django_Python_Django - Fatal编程技术网

Python 使用户电子邮件成为唯一的django

Python 使用户电子邮件成为唯一的django,python,django,Python,Django,当用户注册时,如何使Django用户电子邮件唯一 forms.py class SignUpForm(UserCreationForm): email = forms.EmailField(required=True) class Meta: model = User fields = ("username", "email", "password1", "password2&

当用户注册时,如何使Django用户电子邮件唯一

forms.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
class SignUp(generic.CreateView):
    form_class = SignUpForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'
我使用的是from django.contrib.auth.models用户。 我是否需要覆盖模型中的用户。目前该模型未引用用户

视图.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
class SignUp(generic.CreateView):
    form_class = SignUpForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

Django的文档中有一个很好的例子-

您必须将
AbstractBaseUser
模型中的电子邮件字段声明为
unique=True

class MyUser(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

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

from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
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
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
并使用
AUTH\u USER\u MODEL=“app.CustomUser”
更新设置

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

from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
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
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
更新 如果您处于项目中期,那么您可以按照关于如何更改迁移的说明进行操作,简言之,即:

  • 备份数据库
  • 创建一个与auth.user相同的自定义用户模型,将其称为user(因此多对多表保持相同的名称),并设置db_table='auth_user'(因此它使用相同的表)
  • 删除所有迁移文件(除了
    \uuuuu init\uuuuuu.py
  • 从表中删除所有条目
    django\u迁移
  • 使用
    python manage.py makemigrations创建所有迁移文件
  • 通过
    python manage.py migrate--false运行伪迁移
  • 取消设置数据库表,对自定义模型进行其他更改,生成迁移,应用迁移
  • 但是,如果您刚刚开始,则删除迁移目录中的DB和migrations文件,除了
    \uuuu init\uuuu.py
    。然后创建一个新的数据库,通过
    python manage.py makemigrations
    创建一组新的迁移,并通过
    python manage.py migrate
    应用迁移

    对于其他模型中的引用,您可以将它们引用到
    设置.AUTH\u USER\u MODEL
    ,以避免将来出现任何问题。例如:

    from django.contrib.auth.models import AbstractUser
    
    
    class CustomUser(AbstractUser):
        email = models.EmailField(unique=True)
    
    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
    
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
    

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

    您可能会感兴趣:

    具有所需唯一电子邮件字段和项目中期支持的可重用用户模型

    它定义了对原始表(auth_User)的自定义用户模型重用(如果存在)。如果需要(添加到现有项目中时),它将按正确的顺序重新创建应用迁移的历史记录

    我将感谢您的反馈。

    这是一个工作代码

    在任何models.py中使用以下代码段

    models.py

    from django.contrib.auth.models import User
    
    User._meta.get_field('email')._unique = True
    SETTINGS.PY
    AUTHENTICATION_BACKENDS = [
         'django.contrib.auth.backends.ModelBackend'
    ]
    
    来自django.contrib.auth.models导入用户
    用户。_meta.get_字段('email')。_unique=True
    
    django版本:3.0.2


    参考:Django 3.1的工作代码

    models.py

    from django.contrib.auth.models import User
    
    User._meta.get_field('email')._unique = True
    SETTINGS.PY
    AUTHENTICATION_BACKENDS = [
         'django.contrib.auth.backends.ModelBackend'
    ]
    

    使用
    AbstractBaseUser

    #forms.py
    from django.core.exceptions import ValidationError
    from django.contrib.auth.models import User
    from django.contrib.auth.form import UserCreationForm
    from some_app.validators import validate_email
    
    def validate_email(value):
        if User.objects.filter(email = value).exists():
            raise ValidationError((f"{value} is taken."),params = {'value':value})
    
    class UserRegistrationForm(UserCreationForm):
            email = forms.EmailField(validators = [validate_email])
            
            class Meta:
                model = User
            fields = ['username', 'email', 'password1', 'password2']    
        
    

    在使用CustomUser模型继承自
    AbstractBaseUser
    的情况下,您可以覆盖
    full\u clean()
    方法来验证您指定的模型字段上的唯一约束
    unique=True
    。这比表单(即
    FormClass
    )验证更安全

    示例

    从django.contrib.auth.models导入AbstractBaseUser
    从django.db导入模型
    类CustomUser(AbstractBaseUser):
    email=models.EmailField(unique=True)
    # ...
    def完全清洁(自清洁,**kwargs):
    """
    在模型上调用clean_fields()、clean()和validate_unique()。
    针对发生的任何错误引发ValidationError。
    """
    超级().完全清洁()
    

    注意:在

    上测试,因此当我尝试添加CustomUser时,会出现错误,因为还有其他型号使用django.contrib.auth.User。试图找出我需要做什么来扩展用户模型。我是否需要将所有引用从User更改为CustomUser?@mogoli查看我的评论。您需要删除数据库、迁移等,然后重新开始项目。我知道这是很久以前发布的,但我与上面帖子中的解决方案中的CustomUser有一个问题。我有一个CustomUser带有电子邮件字段,我发现当我想在管理面板中创建新用户时,我遇到了一个完整性错误。错误消息是:“IntegrityError位于/admin/users/customuser/add/。我在启动项目时创建了customuser,但后来添加了电子邮件字段。我想知道这是否是问题所在。重复的键值违反了唯一约束users\u customuser\u email\u 6445acef\u uniq”详细信息:key(email)=()已存在。“@ruddra”您所说的“但如果您不需要在数据库中存储唯一的电子邮件”是什么意思。。。“,检查电子邮件在
    用户表单中是否唯一与在
    用户模型中存储唯一电子邮件不一样吗?e、 g.如果我想使用电子邮件和密码作为登录的主要字段,那么检查电子邮件在
    UserForm
    中是否唯一将是我的工作,或者我应该通过继承
    AbstractUser
    创建
    CustomUser
    模型吗?当我尝试此操作时,不会发生任何事情,我的注册仍然可以接受副本emails@mogoli删除数据库和迁移。在settings.py中,添加
    AUTH\u USER\u MODEL='new\u USER\u MODEL.MyUser'。然后运行
    python manage.py makemigrations new\u user
    。最后,运行
    python manage.py migrate`。到目前为止,将用户模型电子邮件地址约束为唯一的最简单方法——如果表中还没有非唯一值,您甚至可以将其合并到现有项目中。