97 votes

Le manager n'est pas disponible ; l'utilisateur a été remplacé par 'pet.Person'.

J'utilise le modèle d'utilisateur par défaut de django depuis un certain temps et je me rends compte que si je dois l'améliorer, je dois créer mon propre modèle d'utilisateur personnalisé dans django 1.5.

J'ai créé mon modèle d'utilisateur personnalisé et j'ai une fonction qui permet aux utilisateurs de se connecter. Je pense que mon modèle d'utilisateur personnalisé est incompatible avec ma fonction car il ne me permettrait pas de faire request.user . Comment puis-je résoudre ce problème pour pouvoir à nouveau utiliser request.user ?

vues

 def LoginRequest(request):
         form = LoginForm(request.POST or None)    
    if request.user.is_authenticated():
             username = User.objects.get(username=request.user)
             url = reverse('world:Profile', kwargs = {'slug': person.slug})
             return HttpResponseRedirect(url)       
         if request.POST and form.is_valid():

             user = form.authenticate_user()
             login(request, user)
            username= User.objects.get(username=request.user)
                person = Person.objects.get(user=request.user)
            url = reverse('world:Profile', kwargs = {'slug': person.slug})
             return HttpResponseRedirect(url)

    return render(request, 'login.html',{'form': form})

modèles

 class PersonManager(BaseUserManager):
     def create_user(self, email,date_of_birth, username,password=None,):
         if not email:
             msg = 'Users must have an email address'
             raise ValueError(msg)

         if not username:
              msg = 'This username is not valid'
        raise ValueError(msg)

         if not date_of_birth:
             msg = 'Please Verify Your DOB'
             raise ValueError(msg)

         user = self.model(

 email=PersonManager.normalize_email(email),username=username,date_of_birth=date_of_birth)

         user.set_password(password)
         user.save(using=self._db)
         return user

     def create_superuser(self,email,username,password,date_of_birth):
         user = self.create_user(email,password=password,username=username,date_of_birth=date_of_birth)
         user.is_admin = True
         user.is_staff = True
         user.is_superuser = True
         user.save(using=self._db)
         return user

 class Person(AbstractBaseUser, PermissionsMixin):

     email = models.EmailField(verbose_name='email address',max_length=255,unique=True,db_index=True,)
     username = models.CharField(max_length=255, unique=True)
     date_of_birth = models.DateField()

     USERNAME_FIELD = 'email'
     REQUIRED_FIELDS = ['username', 'date_of_birth',]

     is_active = models.BooleanField(default=True)
     is_admin = models.BooleanField(default=False)
     is_staff = models.BooleanField(default=False)

     objects = PersonManager()

     def get_full_name(self):
         return self.email

     def get_short_name(self):
         return self.email

     def __unicode__(self):
         return self.email

200voto

Le problème est que User se réfère à django.contrib.auth.models.User et maintenant vous avez un Custom User pet.Person en supposant que vous avez dans le settings.py

AUTH_USER_MODEL = "pet.Person"

vous devez définir User avec le Custom User et vous pouvez le faire avec get_user_model en haut du fichier où vous utilisez User

from django.contrib.auth import get_user_model
User = get_user_model()

vous pourrez désormais utiliser Custom User et le problème a été corrigé.

11voto

justbecause Points 147

Pour tous ceux qui pourraient rencontrer ce problème, je l'ai également résolu en faisant simplement ceci sur forms.py :

ajouter ceci en haut du fichier forms.py

from .models import YourCustomUser

puis ajoutez ceci à votre forms.py CustomUser formulaire :

class SignUpForm(UserCreationForm):
#profile_year        = blaaa blaa blaaa irrelevant.. You have your own stuff here don't worry about it

   # here is the important part.. add a class Meta-
   class Meta:
      model = YourCustomUser #this is the "YourCustomUser" that you imported at the top of the file  
      fields = ('username', 'password1', 'password2', #etc etc, other fields you want displayed on the form)

NOTES IMPORTANTES, ATTENTION :

  1. Ce code a fonctionné dans mon cas. J'ai une vue pour l'inscription des utilisateurs, j'avais un problème ici et je l'ai résolu, je ne l'ai pas essayé pour la connexion des utilisateurs.

  2. En include = () est nécessaire, ou vous pouvez ajouter exclude = () mais il faut en avoir un

9voto

J-a-n-u-s Points 658

Mise en garde importante pour mettre à jour les solutions ci-dessus... Si vous êtes confronté à ce genre de problème, vous avez probablement essayé diverses solutions sur le web vous disant d'ajouter des fichiers de type AUTH_USER_MODEL = users.CustomUser a settings.py puis d'ajouter le code suivant à views.py forms.py et tout autre fichier qui appelle User :

from django.contrib.auth import get_user_model
User = get_user_model()

Et ensuite vous vous grattez la tête quand vous obtenez l'erreur :

Manager isn't available; 'auth.User' has been swapped for 'users.User'

Chaque fois que votre code fait référence User comme :

User.objects.get()

Parce que tu sais que tu as déjà mis objects = UserManager() dans votre classe d'utilisateur personnalisée ( UserManager étant le nom de votre gestionnaire personnalisé qui étend BaseUserManager ).

Eh bien, il s'avère que oui :

User = get_user_model() # somewhere at the top of your .py file
# followed by
User.objects.get() # in a function/method of that same file

N'est PAS équivalent à :

get_user_model().objects.get() # without the need for User = get_user_model() anywhere

Peut-être pas intuitif, mais il s'avère qu'en python, l'exécution de User = get_user_model() une seule fois au moment de l'importation n'entraîne pas alors User être défini lors d'appels ultérieurs (c'est-à-dire qu'il ne se transforme pas en un système de gestion de la qualité). User en une sorte de "constante" à laquelle vous pouvez vous attendre si vous venez d'un environnement C/C++ ; ce qui signifie que l'exécution de User = get_user_model() se produit au moment de l'importation, mais est ensuite déréférencé avant l'appel ultérieur à la classe ou à la fonction/méthode dans ce fichier).

Donc, pour résumer, dans tous les fichiers qui font référence à l'élément User (par exemple, en appelant des fonctions ou des variables telles que User.objects.get() User.objects.all() User.DoesNotExist etc...) :

# Add the following import line
from django.contrib.auth import get_user_model

# Replace all references to User with get_user_model() such as...
user = get_user_model().objects.get(pk=uid)
# instead of  user = User.objects.get(pk=uid)
# or
queryset = get_user_model().objects.all()
# instead of queryset = User.objects.all()
# etc...

J'espère que cela fera gagner du temps à d'autres...

4voto

Owen Murithi Points 41

Sur forms.py

# change
from django.contrib.auth.models import User

# to
from django.contrib.auth import get_user_model

Puis ajoutez le code suivant en haut

User = get_user_model()

-4voto

Afrikan_patriot Points 53

Toutes les solutions fournies ci-dessus n'ont pas fonctionné dans mon cas. Si vous utilisez la version 3.1 de Django, il existe une autre solution pour vous :

Dans auth/forms, commentez la ligne 10 et changez le modèle dans la ligne 104 & 153 à votre modèle défini.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X