Из документов Django.Contrib.Auth :
Расширение пользователя Django по умолчанию. Если вас полностью устраивает модель пользователя Django и вы просто хотите добавить дополнительную информацию о профиле, вы можете просто создать подкласс
django.contrib.auth.models.AbstractUser
и добавить свои настраиваемые поля профиля. Этот класс обеспечивает полную реализацию пользователя по умолчанию в виде абстрактной модели.
Сказано и сделано. Я создал новую модель, как показано ниже:
class MyUser(AbstractUser):
some_extra_data = models.CharField(max_length=100, blank=True)
Это отображается в админке почти как стандарт Django User
. Однако наиболее важным отличием админки является то, что поле пароля (повторно) отсутствует, а вместо него отображается обычное поле CharField. Мне действительно нужно переопределить что-то в admin-config, чтобы это работало? Если да, то как я могу сделать это СУХИМ способом (то есть без копирования материала из исходного кода Django ... фу ...)?
Ответ Нико был чрезвычайно полезным, но я обнаружил, что Django все еще ссылается на модель 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)
источник
forms.ValidationError
имеет второй аргумент:code='duplicate_username'
: github.com/django/django/blob/1.6/django/contrib/auth/... Кроме того , я попробовал это на 1.6.5 и, по какой - то причине, я вообще не нужно было переопределять,UserChangeForm
и форма изменения отлично работала с моим настраиваемым полем. Я не могу объяснить почему. Похоже, это не должно было работать из-заUserChangeForm
наличия классаmodel = User
: github.com/django/django/blob/1.6.5/django/contrib/auth/…Более простое решение, admin.py:
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 для создания и изменения. Я использую Django 1.6.2.
источник
None
вы можете ввести строку, и она будет использоваться в качестве заголовка раздела в форме администратораERRORS: <class 'users.admin.CustomerUserAdmin'>: (admin.E005) Both 'fieldsets' and 'fields' are specified.
Ответ 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)
источник
Еще одно подобное решение ( взято отсюда ):
from __future__ import unicode_literals from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import AbstractUser from django.utils.translation import ugettext_lazy as _ from .models import User class UserAdminWithExtraFields(UserAdmin): def __init__(self, *args, **kwargs): super(UserAdminWithExtraFields, self).__init__(*args, **kwargs) abstract_fields = [field.name for field in AbstractUser._meta.fields] user_fields = [field.name for field in self.model._meta.fields] self.fieldsets += ( (_('Extra fields'), { 'fields': [ f for f in user_fields if ( f not in abstract_fields and f != self.model._meta.pk.name ) ], }), ) admin.site.register(User, UserAdminWithExtraFields)
источник
Просто сделайте следующее
from django.contrib import admin from .models import MyUser admin.site.register(MyUser, admin.ModelAdmin)
Вот и все. Будут показаны все поля модели MyUser. Список отображаемых полей UserAdmin жестко запрограммирован (см. Его исходный код), а ModelAdmin - нет. Это гибко.
источник
ModelAdmin
, а не настроенноеUserAdmin
. Результат - беспорядок.