tutorial - the django project
Error de modelo de usuario personalizado (2)
Estoy intentando configurar mi modelo de usuario personalizado en Django. El motivo es que quiero usar el correo electrónico como nombre de usuario y eliminar por completo el campo de nombre de usuario. Me encontré con un error, que simplemente no puedo entender.
Manager isn''t available; User has been swapped for ''app.MyUser''
Exception Location: .../django/db/models/manager.py in __get__, line 256
Python Version: 2.7.3
Python Path:
[...project specific files,
''/usr/lib/python2.7'',
''/usr/lib/python2.7/plat-linux2'',
''/usr/lib/python2.7/lib-tk'',
''/usr/lib/python2.7/lib-old'',
''/usr/lib/python2.7/lib-dynload'',
''/usr/local/lib/python2.7/dist-packages'',
''/usr/lib/python2.7/dist-packages'',
''/usr/lib/python2.7/dist-packages/PIL'',
''/usr/lib/python2.7/dist-packages/gtk-2.0'',
''/usr/lib/pymodules/python2.7'',
''/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode'']
He buscado en Google como loco, pero no he encontrado demasiadas páginas sobre este mensaje de error. He encontrado algunas páginas, con sugerencias sobre cómo resolverlo, pero ninguna de las sugerencias me ha funcionado.
Mi código: configuré el modelo de usuario personalizado. He declarado el modelo de usuario personalizado AUTH_USER_MODEL = ''app.MyUser''
en settings.py. También he configurado un UserManager personalizado:
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email. Note that none of the optional fields gets values in the creation. These fields will have to be filled out later on.
"""
if not email:
raise ValueError(''Users must have an email address'')
user = self.model(email=MyUserManager.normalize_email(email))
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None):
"""
Creates and saves a superuser with the the above mentioned attributes
"""
user = self.create_user(email, password=password)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser, PermissionsMixin):
"""
Custom made User model. No username, instead email is used as unique field and index
"""
Genders = ((''M'', ''Man''), (''K'', ''Woman''))
FirstName = models.CharField(max_length=30)
LastName = models.CharField(max_length=40)
Gender = models.CharField(max_length=2, choices=Genders, default=''K'')
email = models.EmailField(verbose_name=''email address'', max_length=255, unique=True, db_index=True,)
twitter = models.CharField(max_length=30)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = ''email''
REQUIRED_FIELDS = []
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __unicode__(self):
return self.email
objects = MyUserManager()
Intenté declarar a diferentes tipos de UserAdmins, ninguno de los cuales está haciendo ninguna diferencia, el primero que probé fue;
class MyUserAdmin(UserAdmin):
# The forms to add and change user instances
#form = UserChangeForm
#add_form = FrontpageRegistrationForm
list_display = (''email'', ''FirstName'', ''LastName'', ''Gender'', ''twitter'')
list_filter = ()
add_fieldsets = ((None, {''classes'': (''wide'',),''fields'': (''email'', ''password1'', ''password2'')}),)
search_fields = (''email'',)
ordering = (''email'',)
filter_horizontal = ()
admin.site.register(MyUser, MyUserAdmin)
add_form
los dos atributos add_form
y form
porque generaron algunos errores de forma en los que quería volver en un momento posterior.
Se realizó el segundo UserAdmin, después de leer sobre una posible solución aquí . Esto no ayudó a la situación;
class MyUserAdmin(admin.ModelAdmin):
# The forms to add and change user instances
#form = UserChangeForm
add_form = FrontpageRegistrationForm
add_fieldsets = ((None, {''classes'': (''wide'',),''fields'': (''email'', ''password1'', ''password2'')}),)
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(MyUserAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
defaults = {}
if obj is None:
defaults.update({''form'': self.add_form,''fields'': admin.util.flatten_fieldsets(self.add_fieldsets),})
defaults.update(kwargs)
return super(MyUserAdmin, self).get_form(request, obj, **defaults)
También intenté eliminar todas las tablas en el db sin suerte.
Estaría eternamente agradecido a cualquiera que incluso vea el problema. Y si alguien resolviera esto, haría todo lo posible por convencer a mi esposa para que nombrara a nuestro primogénito después del Avatar que me dio una solución para poder seguir viviendo mi vida.
EDITAR: Intenté configurar AUTH_USER_MODEL
para mainfolder.app.MyUser
Estoy seguro de que la "carpeta principal" está en el camino de los pitones. init .py en la aplicación debería ser correcto. El nuevo settings.py dio el siguiente error de servidor; auth.user: AUTH_USER_MODEL is not of the form ''app_label.app_name''.admin.logentry: ''user'' has a relation with model smartflightsearch.SFSdb.MyUser, which has either not been installed or is abstract.registration.registrationprofile: ''user'' has a relation with model, which has either not been installed or is abstract.
Una nueva pista que no sé cómo interpretar ...
Cuando dijiste que estableciste AUTH_USER_MODEL = ''app.MyUser''
supongo que tu aplicación donde está ubicada la clase MyUser
, tiene una estructura, perharps, como esta:
dentro de la aplicación / dir: init .py y models.py y cosas ...
así que dentro de models.py tienes MyUser
y dentro de init .py:
from models import MyUser
TL; DR: utilice el código de la parte de Solución al final de la siguiente respuesta.
Explicación más larga: Verá, a partir de Django 1.5 , no es suficiente subclasificar UserAdmin
de Django para poder interactuar con modelos de usuarios intercambiables: también debe sobrescribir los formularios respectivos.
Si django.contrib.auth.admin
fuente django.contrib.auth.admin
, verá que el form
add_form
y add_form
tienen estos valores:
# django/contrib/auth/admin.py
class UserAdmin(admin.ModelAdmin):
...
form = UserChangeForm
add_form = UserCreationForm
Lo que nos django.contrib.auth.forms
formas en django.contrib.auth.forms
que no respetan los modelos de usuario intercambiables:
# django/contrib/auth/forms.py
class UserCreationForm(forms.ModelForm):
...
class Meta:
model = User # non-swappable User model here.
class UserChangeForm(forms.ModelForm):
...
class Meta:
model = User # non-swappable User model here.
Solución: Entonces, debes seguir una gran respuesta ya existente ( ¡no olvides votarla! ) Que se reduce a esto:
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class MyUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
class MyUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
add_form = MyUserCreationForm
admin.site.register(MyUser, MyUserAdmin)
Con suerte, esto se solucionaría en las versiones futuras de Django (aquí está el ticket correspondiente en el rastreador de errores).