将Django auth UserAdmin用于自定义用户模型
从Django.Contrib.Auth文档 :
扩展Django的默认用户如果你对Django的用户模型完全满意,而你只是想添加一些额外的configuration文件信息,你可以简单地
django.contrib.auth.models.AbstractUser
并添加你的自定义configuration文件字段。 该类提供了默认用户的完整实现作为抽象模型。
说完了。 我创build了如下的新模型:
class MyUser(AbstractUser): some_extra_data = models.CharField(max_length=100, blank=True)
这显示在pipe理员几乎像Django的标准User
。 但是,admin中最重要的区别是密码 – (重新)设置字段不存在,而是显示正常的CharField。 我真的必须重写pipe理configuration中的东西来得到这个工作吗? 如果是这样,我该怎么做,有点干的方式(即没有从Django源复制东西…呃…)?
在Django源代码周围挖了一会之后,我发现了一个有效的工作。 我并不完全满意这个解决scheme,但它似乎工作。 随意提出更好的解决scheme!
Django使用UserAdmin
为User
模型渲染漂亮的pipe理外观。 通过在我们的admin.py
文件中使用这个,我们可以得到与我们的模型相同的外观。
from django.contrib.auth.admin import UserAdmin admin.site.register(MyUser, UserAdmin)
但是,这本身可能不是一个好的解决scheme,因为Django Admin不会显示任何特殊字段。 有两个原因:
-
UserAdmin
使用UserChangeForm
作为修改对象时使用的表单,该对象依次使用User
作为其模型。 -
UserAdmin
定义了一个formsets
属性,稍后由UserChangeForm
,它不包含你的特殊字段。
所以,我创build了一个特殊的改变forms,它重载Meta内部类,使改变forms使用正确的模型。 我也不得不重载UserAdmin
来将我的特殊字段添加到字段集,这是我不喜欢的解决scheme的一部分,因为它看起来有点难看。 随意build议改进!
from django.contrib.auth.admin import UserAdmin from django.contrib.auth.forms import UserChangeForm class MyUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = MyUser class MyUserAdmin(UserAdmin): form = MyUserChangeForm fieldsets = UserAdmin.fieldsets + ( (None, {'fields': ('some_extra_data',)}), ) admin.site.register(MyUser, MyUserAdmin)
nico的答案非常有帮助,但我发现Django在创build新用户时仍然引用了User模型。
门票#19353引用此问题。
为了解决它,我不得不做一些更多的admin.py
admin.py:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.forms import UserChangeForm, UserCreationForm from main.models import MyUser from django import forms class MyUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = MyUser class MyUserCreationForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = MyUser def clean_username(self): username = self.cleaned_data['username'] try: MyUser.objects.get(username=username) except MyUser.DoesNotExist: return username raise forms.ValidationError(self.error_messages['duplicate_username']) class MyUserAdmin(UserAdmin): form = MyUserChangeForm add_form = MyUserCreationForm fieldsets = UserAdmin.fieldsets + ( (None, {'fields': ('extra_field1', 'extra_field2',)}), ) admin.site.register(MyUser, MyUserAdmin)
更简单的解决scheme:
from django.contrib.auth.admin import UserAdmin from main.models import MyUser class MyUserAdmin(UserAdmin): model = MyUser fieldsets = UserAdmin.fieldsets + ( (None, {'fields': ('some_extra_data',)}), ) admin.site.register(MyUser, MyUserAdmin)
Django将正确引用MyUser模型进行创build和修改。 我正在使用Django 1.6.2。
当我试图添加一个自定义字段到创build窗体时,cesc的答案不适用于我。 也许它是从1.6.2改变的? 无论哪种方式,我发现将字段添加到两个字段集和add_fieldsets做的伎俩。
ADDITIONAL_USER_FIELDS = ( (None, {'fields': ('some_additional_field',)}), ) class MyUserAdmin(UserAdmin): model = MyUser add_fieldsets = UserAdmin.add_fieldsets + ADDITIONAL_USER_FIELDS fieldsets = UserAdmin.fieldsets + ADDITIONAL_USER_FIELDS admin.site.register(MyUser, MyUserAdmin)