【问题标题】:Can the User model be overridden to make the email field required?可以覆盖用户模型以使电子邮件字段成为必需吗?
【发布时间】:2023-03-08 19:43:01
【问题描述】:

对于我的应用程序,Django User model 中的电子邮件字段应该是必需的,但默认情况下它是可选的。

我搜索了这个问题,但我发现的大多数答案都是关于在自定义 UserCreationForm for example 中设置所需的电子邮件字段:

class CustomUserForm(UserCreationForm):
    """Provide a view for creating users with only the requisite fields."""

    class Meta:
        model = User
        # Note that password is taken care of for us by auth's UserCreationForm.
        fields = ('username', 'email')

    def __init__(self, *args, **kwargs):
        super(CustomUserForm, self).__init__(*args, **kwargs)
        self.fields['email'].required = True

但我也想在 User 模型中强制使用电子邮件,因为我在想 ModelForm 可能是前端的东西,并且用户可能会关闭所需的条件使用 chrome 开发工具,我错了吗?在ModelForm 中设置所需的电子邮件是否与在用户model 中设置相同,或者我可以覆盖用户模型以使电子邮件成为必需?

【问题讨论】:

  • 表单只是前端,如果你使用表单来处理数据(通常构造CustomUserForm(request.POST),它也会在服务器端验证,如果用户已输入email 地址)。

标签: django django-models django-forms django-authentication


【解决方案1】:

在您的设置文件中

AUTH_USER_MODEL = 'yourapp.User'

在你的模型中

from django.db import models
from django.contrib.auth.models import AbstractUser, Permission, Group
from django.utils.translation import gettext_lazy as _


class User(AbstractUser):
    groups = models.ManyToManyField(
        Group,
        verbose_name=_('groups'),
        blank=True,
        help_text=_(
            'The groups this user belongs to. A user will get all permissions '
            'granted to each of their groups.'
        ),
        related_name="user_groups",
        related_query_name="user",
    )
    user_permissions = models.ManyToManyField(
        Permission,
        verbose_name=_('user permissions'),
        blank=True,
        help_text=_('Specific permissions for this user.'),
        related_name="user_permissions",
        related_query_name="user",
    )

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['email']

    # here you can add new fields and attributes

    class Meta:
        permissions = (
            # here you can add pressiion
        )

在您的管理员中

from custodia.models import User
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import gettext_lazy as _


@admin.register(User)
class UserAdmin(UserAdmin):
    list_display = ('email', 'first_name', 'last_name', 'customer', 'is_staff', 'is_active')
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        (_('Aditional info'), {'fields': ('your_new_fields',)}),
        (_('Permissions'), {
            'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
        }),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )

    list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups', 'customer')

【讨论】:

  • 我对 Django 很陌生,所以我不明白,如果我们继承自 AbstractUser,那么为什么我们需要添加这么多东西,例如 groupsuser_permissions 等。 AbstractUser 不会处理所有这些吗?还有,我看不懂admin.py里的代码,是干什么用的?
  • 只有在使用管理站点时才需要管理文件
【解决方案2】:

也许 ModelForm 是一个前端的东西,用户可能通过使用 chrome 开发工具关闭了所需的条件,我错了吗?

您是正确的,用户可以使用工具来制作不需要的输入项,实际上您通常可以更改 DOM 从而更改 HTML 表单,或者更简单地使用像 curl 这样的工具来制作一个 POST 请求,您可以在其中发布任意数据。

但是Form(在一定程度上是ModelForm)确实仅在HTML中呈现表单,它还用于验证数据。因此,这意味着如果您使用以下视图:

def my_view(request):
    if request.method == 'POST':
        form = CustomUserForm(request.POST, request.FILES)
        if form.is_valid():
            # …
        # …
    # …

如果用户没有填写电子邮件地址,form.is_valid() 将返回 False。因此,表单用于验证、清理数据、在模型中存储数据以及呈现 HTML 表单。

【讨论】:

    【解决方案3】:
    from django.contrib.auth.models import User
    from django.db import models
    
    User.add_to_class('email', models.EmailField(blank=False))
    
    
    
    

    【讨论】:

    • 刚才我试过了,但我仍然能够创建一个电子邮件字段为空的用户
    • 如果添加 null=True 请运行 makemigrations
    • 对不起,我没听清楚,我需要在哪里添加 null=True?但我确实运行了 makemigrations
    • 我试过这个User.add_to_class('email', models.EmailField(null=True, blank=False)) 但我收到以下错误:错误:auth.User.email: (models.E006) 字段“电子邮件”与模型字段“电子邮件”冲突auth.user'。
    • 好的,我们可以改变所有的类,让我们放代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 2012-02-12
    • 2017-04-02
    相关资源
    最近更新 更多