Использование Django auth UserAdmin для пользовательской модели пользователя
С Джанго.ВНО.Проверка подлинности документов:
расширение пользователя Django по умолчанию Если вы полностью довольны пользовательской моделью Django, и вы просто хотите добавить дополнительную информацию о профиле, вы можете просто подкласс
django.contrib.auth.models.AbstractUser
и добавьте настраиваемые поля профиля. Этот класс предоставляет полную реализацию пользователя по умолчанию в качестве абстрактной модели.
сказано и сделано. Я создал новую модель, как ниже:
class MyUser(AbstractUser):
some_extra_data = models.CharField(max_length=100, blank=True)
Это появляется в admin почти как стандарт Django User
. Однако самое важное различие в admin заключается в том, что поле password-(re)set отсутствует, но вместо него отображается обычное CharField. Мне действительно нужно переопределить материал в admin-config, чтобы заставить это работать? Если да, то как я могу сделать это несколько сухим способом (т. е. без копирования материала из источника Django... фуу...)?
5 ответов
покопавшись в исходном коде Django некоторое время, я нашел рабочую soultion. Я не совсем доволен этим решением, но, похоже, оно работает. Не стесняйтесь предлагать лучшие решения!
Django использует UserAdmin
чтобы сделать хороший админ искать User
- модели. Просто используя это в нашем admin.py
-файл, мы можем получить такой же взгляд для нашей модели.
from django.contrib.auth.admin import UserAdmin
admin.site.register(MyUser, UserAdmin)
однако это само по себе, вероятно, не является хорошим решением, так как Django Admin не будет отображаться любое из ваших специальных полей. Этому есть две причины:--13-->
-
UserAdmin
используетUserChangeForm
как бланк будет использоваться при изменении объекта, который в свою очередь используетUser
в качестве модели. -
UserAdmin
определяетformsets
-свойство, позже используемоеUserChangeForm
, который не включает ваши специальные поля.
Итак, я создал специальную форму изменения, которая перегружает мета-внутренний класс, так что форма изменения использует правильную модель. Мне тоже пришлось перегрузка 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)
ответ Нико был очень полезен, но я обнаружил, что Django по-прежнему ссылается на модель пользователя при создании нового пользователя.
авиабилет #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)
более простое решение, 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.
ответ 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)