在 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 的默认UserCreationForm
。
first_name
和 last_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)