【问题标题】:Django Abstract BaseUserDjango 抽象 BaseUser
【发布时间】:2014-02-28 09:54:41
【问题描述】:

我可以使用 Django 用户模型提供的相同身份验证系统来为抽象基础用户模型的子类化模型,如果不能,那么我们还能做什么?另外,如何配置 ModelAdmin 以提供对这些模型的管理员访问权限?

【问题讨论】:

  • docs中描述了使用自定义用户模型
  • 是的,但我仍然对模型管理员和用于抽象基本用户的管理类感到困惑,这在文档中没有完全定义

标签: python django django-models django-admin


【解决方案1】:

您更喜欢按原样使用 Django 的内置身份验证系统,这可能表明不需要基于 Abstract Base User 模型替换自定义 User 类。您可能需要考虑使用一对一关系扩展 User 类 (how-to from the docs)。这将允许您保留 Django 的所有默认行为,以及添加您希望用户拥有的任何其他字段、方法等。我们发现这对于我们的大多数情况来说已经足够了,而且比创建一个全新的 Use 类要简单得多。

无论如何,话虽如此,您可以通过从 BaseUserManager 继承并创建新管理器来创建自定义身份验证,然后将自定义用户的 objects 字段分配给这个新管理器。或者,您可以将自定义用户的 objects 字段分配给 Django 的经理。如果您需要某种自定义身份验证(例如,使用电子邮件而不是用户名登录),您应该只创建自己的经理。这是有关如何执行此操作的文档的link

要向 Django 的管理员注册自定义用户模型,您需要在特定应用的 admin.py 文件中执行一些操作。首先,创建用于创建和编辑用户的自定义表单,然后在您的自定义用户管理类中子类化 UserAdmin,并引用您之前创建的表单。最后,使用admin.site.register() 注册新的用户管理员。这是 admin.py 文件的完整示例:

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from customauth.models import MyUser


class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = MyUser
        fields = ('email', 'date_of_birth')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """
    A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = MyUser
        fields = ['email', 'password', 'date_of_birth', 'is_active', 'is_admin']

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class MyUserAdmin(UserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'date_of_birth', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('date_of_birth',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'date_of_birth', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

# Now register the new UserAdmin...
admin.site.register(MyUser, MyUserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)    

完成 admin.py 文件后,使用 settings.py 文件中的 AUTH_USER_MODEL 变量将自定义模型指定为默认用户模型。

AUTH_USER_MODEL = 'customauth.MyUser'

【讨论】:

  • 谢谢 我只是对使用 MyUserAdmin 感到困惑。我也可以使用在 django 用户模型中定义的身份验证功能,或者我必须在 Myusermodel 中再次定义它来验证浏览我网站的任何用户。 @sgarza62
  • 如果您的自定义 User 模型包含 username 字段,那么 Django 内置的 authenticate() 方法就足够了。如果您的 User 模型仅包含例如电子邮件作为唯一标识符,那么您必须在 User 类中将 email 指定为 USERNAME_FIELD。更多信息请通读以下两个交流:[1]stackoverflow.com/questions/16689056/…[2]groups.google.com/forum/#!topic/django-users/4lNWuyv16hg
  • 它仍然无法正常工作我的意思是在以超级用户身份登录管理员后我得到以下信息我的意思是我成功登录但它说>站点管理>您无权编辑任何内容
  • 你使用的是什么版本的 Django?如果它早于 1.7,则在您的 urls.py 文件中,from django.contrib import admin,然后将 admin.autodiscover() 添加到项目的 urls.py 文件中,然后声明您的 urlpatterns。文档链接:docs.djangoproject.com/en/1.6/ref/contrib/admin/…
  • 完成此操作后,如果您仍然遇到权限问题,则可能是您的自定义用户模型需要定义权限。子类化您的用户模型(docs.djangoproject.com/en/1.6/topics/auth/customizing/…)中的PermissionsMixin,如本答案的代码所示(stackoverflow.com/a/15605899/1337422
猜你喜欢
  • 2016-09-01
  • 2014-08-08
  • 2014-12-29
  • 2016-04-15
  • 2018-06-16
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多