AUTH_USER_MODEL
erreur résolue dans EDIT3. Les mots de passe ne seront toujours pas sauvegardés lors de la création de l'utilisateur via le formulaire.
J'utilise Django 1.5 en jouant avec les nouvelles fonctionnalités de substitution/extension des utilisateurs, et je ne peux pas enregistrer de nouveaux utilisateurs via mon formulaire d'enregistrement - uniquement via l'administrateur. Lors de l'inscription via le formulaire d'inscription, j'obtiens l'erreur suivante:
Manager isn't available; User has been swapped for 'poker.PokerUser'
models.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)
modèle PokerUserForm
:
class PokerUserForm(UserCreationForm):
class Meta:
model = PokerUser
fields = ('username','password1','password2','email','user_type','token','username1','username2','username3','username4','username5',)
J'ai tenté de modifier le modèle dans le modèle PokerUserForm
pour qu'il utilise get_user_model()
au lieu de le définir explicitement en définissant model = get_user_model()
au lieu de model = PokerUser
, mais le message d'erreur suivant s'affiche:
Django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed
Mon AUTH_USER_MODEL
est configuré dans mon settings.py
comme suit:
AUTH_USER_MODEL = 'poker.PokerUser'
On y va - ma vue d’enregistrement dans 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:
Selon la documentation , la UserCreationForm
doit être recréée pour pouvoir être utilisée avec des classes d'utilisateurs personnalisées.
J'ai remplacé la UserCreationForm
entière comme suit:
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
Et cela a pu résoudre cette erreur:
The Manager isn't available; User has been swapped for 'poker.PokerUser'
À présent, les utilisateurs sont créés mais ne peuvent pas se connecter. Lorsque je vérifie les utilisateurs dans l'admin, toutes les informations semblent correctes, à l'exception du mot de passe. L'ajout manuel d'un mot de passe dans l'administrateur ne semble pas fonctionner correctement. Néanmoins, l'ajout d'utilisateurs via l'administrateur fonctionne correctement.
EDIT 2:
Je n'arrive toujours pas à me connecter à aucun de mes modèles AbstractUser créés via le formulaire d'inscription. J'ai complètement remplacé la UserCreationForm
comme indiqué ci-dessus et je suis incapable d'implémenter get_user_model()
avec cette erreur:
AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed
Le code Django pour get_user_model()
est:
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
Depuis que AUTH_USER_MODEL = 'poker.PokerUser'
est configuré dans mon settings.py
, cela devrait fonctionner. J'ai vérifié cela via la console 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
Cependant, la mise en œuvre ne fonctionne toujours pas correctement.
Si vous avez lu jusqu'ici, merci!
EDIT3:
AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed
a été corrigé. J'ai accidentellement eu la UserCreationForm
que j'ai recréé dans poker.models
au lieu de registration.forms
. Ainsi, lorsque j'ai exécuté get_user_model()
qui a été affecté à poker.PokerUser
, le problème n'a pas pu être résolu car il se trouvait déjà à cet emplacement.
Maintenant, le seul problème est que lors de la création de nouveaux utilisateurs, leurs mots de passe ne seront pas enregistrés. Je l'ai réduite à une seule méthode dans UserCreationForm
en plaçant les instructions d'impression ici:
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
Les instructions print password1
et print password1
dans clean_password2
affichent le mot de passe en texte brut, mais print self.cleaned_data["password1"]
dans la méthode save
est vide. Pourquoi mes données de formulaire ne sont-elles pas transmises à la méthode de sauvegarde?
La création de modèle TL; DRAbstractUser
fonctionne à la fois dans le formulaire d’administrateur et via le formulaire d’inscription, mais seuls les utilisateurs créés via ce dernier peuvent se connecter. Les utilisateurs créés via le formulaire d'inscription ne parviennent pas à se connecter et semblent être enregistrés sans mot de passe. Toutes les autres informations sont enregistrées correctement.
Ok, il y avait trois problèmes ici pour moi, alors je vais les aborder tous car je suis à peu près sûr que les deux premiers reviendront à quelqu'un d'autre.
Manager isn't available; User has been swapped for 'poker.PokerUser'
Cela était dû à l’utilisation mais à la recréation de UserCreationForm
. Lors de l'utilisation de modèles personnalisés dans la version 1.5, certains formulaires de modèle sont disponibles tels quels mais celui-ci doit être recréé. Voir ici pour les documents.
The Manager isn't available; User has been swapped for 'poker.PokerUser'
Alors que AUTH_USER_MODEL = 'poker.PokerUser'
était défini dans mon settings.py
, j’appelais get_user_model()
à partir de l’emplacement poker.models
. Vous devez appeler get_user_model()
à partir d'un autre emplacement. Déplacer mon formulaire vers registration.forms
et appeler get_user_model()
à partir de là fonctionnait correctement.
Ce n'était qu'un fou de cerveau de mon côté. Dans mon modèle UserRegistration
, je manipulais divers champs du formulaire. Lorsque j'ai renvoyé ces champs à UserCreationForm
pour la méthode save()
, je ne leur transmettais pas les champs de mot de passe. Woops!
Je l'ai rencontré quelques fois. Cela a toujours été un problème d'importation. Supposons que nous ayons core/models.py, qui implémente un utilisateur personnalisé et importe un symbole depuis un autre fichier (par exemple, Else):
from Something import Else
class CustomUser(AbstractBaseUser):
pass
Et puis nous avons un autre fichier qui utilise CustomUser et définit également Else. Appelons cela quelque chose/models.py:
from core.models import CustomUser
class Else(models.Model):
pass
class AnotherClass(models.model):
user = models.ForeignKey(CustomUser)
Lorsque core/models.py va importer Else, il évalue quelque chose/models.py et aboutit à la définition AnotherClass. AnotherClass utilise CustomUser, mais CustomUser n’a pas encore été installé car nous sommes en train de le créer. Donc, il jette cette erreur.
J'ai résolu ce problème en gardant mon core/models.py autonome. Il importe peu de mes autres applications.
Dans mon cas de mise à jour, l'app_label approprié dans la méta a résolu ce problème.
class APPUser(AbstractUser):
password = models.TextField(blank=True)
class Meta:
app_label = 'app_auth'
db_table = "app_user"