在 Django 的身份验证用户模型中,将名字、姓氏作为必需属性而不是可选属性

Posted

技术标签:

【中文标题】在 Django 的身份验证用户模型中,将名字、姓氏作为必需属性而不是可选属性【英文标题】:Making first name, last name a required attribute rather than an optional one in Django's auth User model 【发布时间】:2012-01-18 00:09:08 【问题描述】:

我正在尝试确保名字和姓氏字段对于 auth User 模型不是可选的,但我不确定如何更改它。我不能使用子类,因为我必须使用身份验证系统。

我能想到的两个解决方案是:

    将名称放在用户个人资料中,但有一个我无法正确使用的字段有点傻。 在表单中而不是在模型中进行验证。我不认为这真的符合 Django 的理念......

由于某种原因,我似乎无法找到在线执行此操作的方法,因此不胜感激。我原以为这会是一个受欢迎的问题。

干杯, 杜兰德

【问题讨论】:

您还可以选择在 Django 安装中修改模型,但这显然也不是一个好选择。 是的,没错,但我想它不是很便携。这个当前的项目实际上不应该是,但它为其他项目设置了一个不好的优先级。 完全。不幸的是,我认为不会有一个完全干净的解决方案。 Django 确实需要一种方法来让您覆盖 User 模型,但仍然允许使用 contrib.auth 和朋友。 我会在表单中进行验证。这是一个非常非侵入性的解决方案,让你用很少的代码重用所有的 auth 用户框架,你认为它在什么方面违背了 django 的理念? 因为验证只能在表单内工作,而不能在其他输入法中工作。我想我会接受你的建议并使用表格。谢谢:) 【参考方案1】:

最简单的解决方案

只需创建一个自定义的 UserRegisterForm 继承 django 的默认 UserCreationFormfirst_namelast_name 已经是 django 的默认 User 的属性。如果您想将它们设为必填字段,请将这些字段重新创建为 forms.CharField(...)

现在使用您自己的用户注册表单。

# Contents usersapp/forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm


# Inherit Django's default UserCreationForm
class UserRegisterForm(UserCreationForm):
    first_name = forms.CharField(max_length=50) # Required
    last_name = forms.CharField(max_length=50) # Required
    # All fields you re-define here will become required fields in the form

    class Meta:
        model = User
        fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2']

【讨论】:

【参考方案2】:

我肯定会在表单上进行验证。如果您愿意,您甚至可以在管理员中进行更多表单验证。

【讨论】:

这似乎是最好的选择。谢谢!【参考方案3】:

感谢姆布索的建议。这是我为感兴趣的人提供的完整实现。在查看源代码之前,让我们看看它的样子:

我已经实现了一个配置文件模型,但是没有它也可以正常工作。

from django.core.exceptions import ValidationError
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.models import User
from apps.profiles.models import Profile


# Define an inline admin descriptor for Profile model
# which acts a bit like a singleton
class UserProfileInline(admin.StackedInline):
    model = Profile
    can_delete = False
    verbose_name_plural = 'profile'


class MyUserChangeForm(UserChangeForm):
    def clean_first_name(self):
        if self.cleaned_data["first_name"].strip() == '':
            raise ValidationError("First name is required.")
        return self.cleaned_data["first_name"]

    def clean_last_name(self):
        if self.cleaned_data["last_name"].strip() == '':
            raise ValidationError("Last name is required.")
        return self.cleaned_data["last_name"]


# Define a new User admin
class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm
    inlines = UserProfileInline,


admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

注意:如果您确实实现了配置文件模型,建议使用 UserProfile 作为名称,因为这是文档中的内容并且似乎是标准(这部分是在我开始从事该项目之前开发的)。如果您使用的是 Django 1.5 或更高版本,请一起跳过 UserProfile 并扩展 User 模型。

【讨论】:

【参考方案4】:

Django 扩展基本用户模型的方式是通过用户配置文件:参见“Storing additional information about users”。

如果它不符合您的需求,django.contrib.auth 只是一个 Django 应用程序,我会简单地分叉它。只要你遵守原版界面,我想你就没有麻烦了。

另一个选项是Pinax - 它内置了 OpenId 支持,您可以将它与您自己的 openid 提供程序一起使用。 OpenId 原生支持是 battery 我真的很想念 Django。

【讨论】:

Pinax 看起来很酷,我必须在其他项目中使用它,但现在这个非常简单。谢谢!

以上是关于在 Django 的身份验证用户模型中,将名字、姓氏作为必需属性而不是可选属性的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Django 的身份验证用户模型配置为具有 UUID(Postgres DB)

没有用户模型的 Django 基于令牌的身份验证

在Django中定制身份验证

Django 1.5:UserCreationForm 和自定义身份验证模型

Django 身份验证模型错误:未定义名称“用户”

无法使用用户名/密码登录令牌端点:drf 令牌身份验证和自定义用户模型,Django