Usar Django auth UserAdmin para un modelo de usuario personalizado
extend user model django (4)
De los documentos de Django.Contrib.Auth :
Ampliación del usuario predeterminado de Django Si está completamente satisfecho con el modelo de usuario de Django y solo desea agregar información de perfil adicional, puede simplemente subclase
django.contrib.auth.models.AbstractUser
y agregar sus campos de perfil personalizados. Esta clase proporciona la implementación completa del usuario predeterminado como modelo abstracto.
Dicho y hecho. Creé un nuevo modelo como a continuación:
class MyUser(AbstractUser):
some_extra_data = models.CharField(max_length=100, blank=True)
Esto aparece en el administrador casi como el User
estándar de Django. Sin embargo, la diferencia más importante en admin es que el campo de contraseña (re) no está presente, pero en su lugar se muestra un CharField normal. ¿Realmente tengo que anular cosas en la configuración de administrador para que esto funcione? Si es así, ¿cómo puedo hacerlo de una manera SECA (es decir, sin copiar cosas de la fuente de Django ... eww ...)?
Después de investigar el código fuente de Django por un tiempo, encontré una alma de trabajo. No estoy totalmente satisfecho con esta solución, pero parece funcionar. ¡Siéntase libre de sugerir mejores soluciones!
Django usa UserAdmin
para UserAdmin
el buen aspecto de administrador para el modelo de User
. Con solo usar esto en nuestro admin.py
admin.py, podemos obtener el mismo aspecto para nuestro modelo.
from django.contrib.auth.admin import UserAdmin
admin.site.register(MyUser, UserAdmin)
Sin embargo, esto solo probablemente no sea una buena solución, ya que Django Admin no mostrará ninguno de sus campos especiales. Hay dos razones para esto:
-
UserAdmin
usaUserChangeForm
como el formulario que se utilizará al modificar el objeto, que a su vez utiliza alUser
como su modelo. -
UserAdmin
define un conjunto deformsets
-propiedad, más tarde utilizado porUserChangeForm
, que no incluye sus campos especiales.
Entonces, creé una forma de cambio especial que sobrecarga la clase interna Meta de modo que la forma de cambio use el modelo correcto. También tuve que sobrecargar UserAdmin
para agregar mis campos especiales al fieldset, que es la parte de esta solución que me disgusta un poco, ya que se ve un poco feo. ¡Siéntase libre de sugerir mejoras!
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)
La respuesta de cesc no me funcionaba cuando intenté agregar un campo personalizado al formulario de creación. Tal vez ha cambiado desde 1.6.2? De cualquier manera, encontré agregar el campo a ambos conjuntos de campos y add_fieldsets hizo el truco.
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)
La respuesta de nico ha sido extremadamente útil, pero encontré que Django todavía hace referencia al modelo de usuario cuando crea un nuevo usuario.
El boleto #19353 referencia a este problema.
Para arreglarlo, tuve que hacer algunas adiciones más a 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)
Una solución más simple, 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 referenciará correctamente el modelo MyUser para creación y modificación. Estoy usando Django 1.6.2.