Использование 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 не будет отображаться любое из ваших специальных полей. Для этого есть две причины:
UserAdmin
используетUserChangeForm
как бланк будет использоваться при изменении объекта, который в свою очередь используетUser
в качестве модели.UserAdmin
определяет aformsets
-свойство, позже используемое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)
ответ Нико был чрезвычайно полезен, но я обнаружил, что 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)