python - usar - modelo de usuarios django
AUTH_USER_MODEL se refiere al modelo.. que no se ha instalado y creado. Los modelos de AbstractUser no pueden iniciar sesiĆ³n (4)
Bueno, aquí había tres problemas para mí, así que voy a abordarlos ya que estoy bastante seguro de que los dos primeros aparecerán para otra persona.
-
Manager isn''t available; User has been swapped for ''poker.PokerUser''
Esto se debió al uso, pero no a la recreación del UserCreationForm
. Cuando se usan modelos personalizados en 1.5, algunos modelos de formularios están disponibles de forma inmediata, pero este debe ser recreado. Vea aquí para los documentos.
-
The Manager isn''t available; User has been swapped for ''poker.PokerUser''
Mientras tenía AUTH_USER_MODEL = ''poker.PokerUser''
configurado en mi settings.py
, estaba llamando a get_user_model()
desde la ubicación poker.models
. Debe llamar a get_user_model()
desde una ubicación diferente. Mover mi formulario a registration.forms
y llamar a get_user_model()
desde allí funcionó correctamente.
- Los nuevos usuarios no ahorran
Esto fue sólo un pedo cerebral en mi extremo. En mi modelo de UserRegistration
, estaba manipulando varios campos del formulario. Cuando pasé esos campos nuevamente a UserCreationForm
para el método save()
, no estaba pasando los campos de contraseña con él. Woops!
AUTH_USER_MODEL
error solucionado en EDIT3. Las contraseñas aún no se guardarán en la creación del usuario a través del formulario.
Estoy usando Django 1.5 jugando con las funciones de anulación / extensión del nuevo usuario, y no puedo registrar nuevos usuarios a través de mi formulario de registro, solo a través del administrador. Al registrarme a través del formulario de registro, obtengo el siguiente error:
Manager isn''t available; User has been swapped for ''poker.PokerUser''
modelos.py:
class PokerUser(AbstractUser):
poker_relate = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
token = models.EmailField()
USER_CHOICES = (
(''1'', ''Staker''),
(''2'', ''Horse'')
)
user_type = models.CharField(choices=USER_CHOICES, max_length=10)
username1 = models.CharField(null=True, blank=True, max_length=40)
username2 = models.CharField(null=True, blank=True, max_length=40)
username3 = models.CharField(null=True, blank=True, max_length=40)
username4 = models.CharField(null=True, blank=True, max_length=40)
username5 = models.CharField(null=True, blank=True, max_length=40)
Modelo de PokerUserForm
:
class PokerUserForm(UserCreationForm):
class Meta:
model = PokerUser
fields = (''username'',''password1'',''password2'',''email'',''user_type'',''token'',''username1'',''username2'',''username3'',''username4'',''username5'',)
He intentado cambiar el modelo en el modelo PokerUserForm
para usar get_user_model()
lugar de definir explícitamente el modelo configurando model = get_user_model()
lugar de model = PokerUser
pero luego recibo el siguiente error:
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model ''poker.PokerUser'' that has not been installed
Mi AUTH_USER_MODEL
está configurado en mi settings.py
así:
AUTH_USER_MODEL = ''poker.PokerUser''
En adelante, mi vista de registro en views.py
:
def UserRegistration(request):
player = PokerUser()
if request.method == ''POST'':
form = PokerUserForm(request.POST, instance=player)
if form.is_valid():
player.email_address = form.cleaned_data[''email'']
player.user_type = form.cleaned_data[''user_type'']
# if player is staker, token is their own email. otherwise their token is their staker''s email and
# their relation is their staker
if player.user_type == ''1'' or player.user_type == ''staker'':
player.token = player.email_address
else:
player.token = form.cleaned_data[''token'']
staker = PokerUser.objects.get(email=player.token)
player.poker_relate = staker
player.save()
return HttpResponseRedirect(''/'')
else:
form = PokerUserForm()
initialData = {''form'': form}
csrfContext = RequestContext(request, initialData)
return render_to_response(''registration/register.html'', csrfContext)
EDIT1:
De acuerdo con los documentos , el UserCreationForm
debe recrearse para su uso con clases de usuario personalizadas.
UserCreationForm
todo el UserCreationForm
siguiente manera:
class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
error_messages = {
''duplicate_username'': _("A user with that username already exists."),
''password_mismatch'': _("The two password fields didn''t match."),
}
username = forms.RegexField(label=_("Username"), max_length=30,
regex=r''^[/w.@+-]+$'',
help_text=_("Required. 30 characters or fewer. Letters, digits and "
"@/./+/-/_ only."),
error_messages={
''invalid'': _("This value may contain only letters, numbers and "
"@/./+/-/_ characters.")})
password1 = forms.CharField(label=_("Password"),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput,
help_text=_("Enter the same password as above, for verification."))
class Meta:
model = PokerUser
fields = (''username'',''password1'',''password2'',''email'',''user_type'',''token'',''username1'',''username2'',''username3'',''username4'',''username5'',)
def clean_username(self):
# Since User.username is unique, this check is redundant,
# but it sets a nicer error message than the ORM. See #13147.
username = self.cleaned_data["username"]
try:
PokerUser.objects.get(username=username)
except PokerUser.DoesNotExist:
return username
raise forms.ValidationError(self.error_messages[''duplicate_username''])
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages[''password_mismatch''])
return password2
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
Y esto fue capaz de resolver este error:
The Manager isn''t available; User has been swapped for ''poker.PokerUser''
Ahora, los usuarios se crean pero no pueden iniciar sesión. Cuando verifico a los usuarios en el administrador, toda la información parece ser correcta, excepto la contraseña. Añadir una contraseña manualmente en el administrador no parece funcionar correctamente. Aún así, agregar usuarios a través del administrador funciona correctamente.
EDIT 2:
Todavía no puedo iniciar sesión como cualquiera de mis modelos de AbstractUser creados a través del formulario de registro. He anulado completamente el UserCreationForm
como se describe anteriormente, y no puedo implementar get_user_model()
con este error:
AUTH_USER_MODEL refers to model ''poker.PokerUser'' that has not been installed
El código de Django para get_user_model()
es:
def get_user_model():
"Return the User model that is active in this project"
from django.conf import settings
from django.db.models import get_model
try:
app_label, model_name = settings.AUTH_USER_MODEL.split(''.'')
except ValueError:
raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form ''app_label.model_name''")
user_model = get_model(app_label, model_name)
if user_model is None:
raise ImproperlyConfigured("AUTH_USER_MODEL refers to model ''%s'' that has not been installed" % settings.AUTH_USER_MODEL)
return user_model
Como tengo la AUTH_USER_MODEL = ''poker.PokerUser''
en mi settings.py
, esto debería funcionar. He verificado esto a través de la consola Django:
>>> from django.contrib.auth import get_user_model
>>> settings.AUTH_USER_MODEL
Out[14]: ''poker.PokerUser''
>>> from django.db.models import get_model
>>> app_label, model_name = settings.AUTH_USER_MODEL.split(''.'')
>>> user_model = get_model(app_label, model_name)
>>> user_model
Out[18]: poker.models.PokerUser
Sin embargo, la implementación todavía no funciona correctamente.
Si has leído hasta aquí, gracias!
EDIT3:
AUTH_USER_MODEL refers to model ''poker.PokerUser'' that has not been installed
se ha corregido. Accidentalmente tuve el UserCreationForm
que recreé en poker.models
en lugar de registration.forms
, así que cuando ejecuté get_user_model()
asignado a poker.PokerUser
, no se pudo resolver porque ya estaba en esa ubicación.
Ahora, el único problema que queda es que al crear nuevos usuarios, sus contraseñas no se guardarán. Lo he reducido a un solo método en el UserCreationForm
colocando las declaraciones impresas aquí:
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
print password1
password2 = self.cleaned_data.get("password2")
print password2
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages[''password_mismatch''])
print password2
return password2
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
print self.cleaned_data["password1"]
if commit:
user.save()
return user
Las declaraciones print password1
e print password1
en clean_password2
muestran la contraseña de texto sin formato, pero print self.cleaned_data["password1"]
en el método de save
está en blanco. ¿Por qué no se pasan mis datos de formulario al método de guardar?
TL; DR. La creación del modelo AbstractUser
funciona tanto en el Administrador como a través del formulario de registro, pero solo los usuarios creados a través del Administrador pueden iniciar sesión. Los usuarios creados a través del formulario de registro no pueden iniciar sesión y parecen estar guardados sin una contraseña; toda la demás información se guarda correctamente.
En mi caso actualizando, la app_label correcta en meta resolvió este problema
class APPUser(AbstractUser):
password = models.TextField(blank=True)
class Meta:
app_label = ''app_auth''
db_table = "app_user"
Me he topado con esto unas cuantas veces. Siempre ha sido un problema de importación. Supongamos que tenemos core / models.py que implementa un usuario personalizado e importa un símbolo de otro archivo (diga Else):
from Something import Else
class CustomUser(AbstractBaseUser):
pass
Y luego tenemos otro archivo que usa CustomUser y también define Else. Llamemos a esto algo / modelos.py:
from core.models import CustomUser
class Else(models.Model):
pass
class AnotherClass(models.model):
user = models.ForeignKey(CustomUser)
Cuando core / models.py va a importar Else, evalúa algo / models.py y se ejecuta en la definición de AnotherClass. AnotherClass usa CustomUser, pero CustomUser aún no se ha instalado porque estamos en el proceso de crearlo. Por lo tanto, arroja este error.
Resolví este problema manteniendo mi core / models.py independiente. No importa mucho de mis otras aplicaciones.
Para citar los documentos de Django:
También deberá registrar su modelo de usuario personalizado con el administrador. Si su modelo de usuario personalizado amplía el django.contrib.auth.models.AbstractUser, puede utilizar la clase django.contrib.auth.admin.UserAdmin existente de Django.
Verifique el contenido de su archivo admin.py
y asegúrese de registrar su modelo personalizado con el sistema de administración utilizando la clase django.contrib.auth.admin.UserAdmin
.