web-dev-qa-db-fra.com

AUTH_USER_MODEL fait référence au modèle .. qui n'a pas été installé ni créé. Les modèles AbstractUser ne peuvent pas se connecter.

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.

21
Dan Hoerst

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.

  • Les nouveaux utilisateurs n'économisent pas

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!

12
Dan Hoerst

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.

9
Rob Jones

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"
0
naren