Использование Django auth UserAdmin для пользовательской модели пользователя
Из Django.Contrib.Auth docs:
Расширение пользователя по умолчанию DjangosЕсли вы полностью довольны моделью Djangos User и просто хотите добавить дополнительную информацию о профиле, вы можете просто подклассом django.contrib.auth.models.AbstractUser
и добавить свои собственные поля профиля. Этот класс обеспечивает полную реализацию пользователя по умолчанию как абстрактную модель.
Сказал и сделал. Я создал новую модель, как показано ниже:
class MyUser(AbstractUser):
some_extra_data = models.CharField(max_length=100, blank=True)
Это появляется в админах почти как стандарт Django User
. Тем не менее, самое важное отличие администратора заключается в том, что поле set password-(re) отсутствует, но вместо этого отображается обычный CharField. Нужно ли мне переопределять вещи в admin-config, чтобы заставить это работать? Если да, то как я могу сделать это несколько сухим способом (т.е. Без копирования материала из источника Django... eww...)?
Ответы
Ответ 1
После копания вокруг исходного кода Django я нашел рабочую душу. Я не совсем доволен этим решением, но, похоже, он работает. Не стесняйтесь предлагать лучшие решения!
Django использует UserAdmin
для визуализации приятного поведения администратора для модели User
. Просто используя это в нашем admin.py
-file, мы можем получить тот же подход к нашей модели.
from django.contrib.auth.admin import UserAdmin
admin.site.register(MyUser, UserAdmin)
Однако это само по себе, вероятно, не очень хорошее решение, поскольку Django Admin не будет отображать какие-либо из ваших специальных полей. Для этого есть две причины:
-
UserAdmin
использует UserChangeForm
как форму, которая будет использоваться при модификации объекта, который в свою очередь использует User
в качестве своей модели.
-
UserAdmin
определяет formsets
-property, позже используемый UserChangeForm
, который не включает ваши специальные поля.
Итак, я создал специальную форму изменения, которая перегружает внутренний класс Meta, чтобы форма изменения использовала правильную модель. Мне также пришлось перегружать UserAdmin
, чтобы добавить свои специальные поля в набор полей, который является частью этого решения. Мне не нравится бит, поскольку он выглядит немного уродливым. Не стесняйтесь предлагать улучшения!
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)
Ответ 2
Ответ nico был чрезвычайно полезен, но я обнаружил, что Django по-прежнему ссылается на модель User при создании нового пользователя.
Ticket # 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)
Ответ 3
Более простое решение:
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.
Ответ 4
Ответ 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)