将Django auth用户模型中的名和姓设置为必填属性而非可选属性

13 投票
4 回答
6417 浏览
提问于 2025-04-17 08:10

我想确保在用户认证模型中,名字和姓氏这两个字段是必填的,但我不知道该怎么改。因为我必须使用认证系统,所以不能用子类。

我想到的两个解决办法是:

  1. 把名字放在用户资料里,但这样做有点傻,因为我不能正确使用这个字段。
  2. 在表单中进行验证,而不是在模型中。我觉得这样做不太符合Django的设计理念……

出于某种原因,我在网上找不到解决办法,所以任何帮助都很感激。我本以为这个问题会很受欢迎。

谢谢,
Durand

4 个回答

4

感谢Mbuso的建议。这里是我完整的实现,供有兴趣的人参考。在看源代码之前,先来看看它的样子:

管理后台截图

我实现了一个用户资料模型,不过其实没有这个模型也可以正常工作。

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模型。

8

最简单的解决方案

  • 只需创建一个自定义的 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']
3

我建议在表单上进行验证。你甚至可以在管理后台增加更多的表单验证,如果你觉得这样做有必要的话。

撰写回答