Manager ist nicht verfügbar; Benutzer wurde gegen 'pet.Person' getauscht

76

Ich verwende das Standardbenutzermodell in Django schon seit einiger Zeit und mir ist klar, dass ich mein eigenes benutzerdefiniertes Benutzermodell in Django 1.5 erstellen muss, wenn ich es weiter verbessern muss.

Ich habe mein benutzerdefiniertes Benutzermodell erstellt und habe eine Funktion, mit der sich Benutzer anmelden können. Ich denke, mein benutzerdefiniertes Benutzermodell ist nicht mit meiner Funktion kompatibel, da ich damit nicht request.user ausführen kann. Wie kann ich das beheben, damit ich request.user wieder verwenden kann?

Ansichten

 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})

Modelle

 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
JackRoster
quelle

Antworten:

158

Das Problem ist, dass Usersich auf django.contrib.auth.models.Userund jetzt haben Sie eine Custom User pet.PersonAnnahme, die Sie in der habensettings.py

AUTH_USER_MODEL = "pet.Person"

Sie müssen Usermit dem Custom UserModell definieren und können dies get_user_modeloben in der Datei tun, in der Sie es verwendenUser

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

Jetzt können Sie das Custom UserModell verwenden und das Problem wurde behoben.

Victor Castillo Torres
quelle
Hallo, das sieht so aus, als würde es mein Problem lösen. Ich habe mich gefragt, in welche Datei dieser Code gehen soll. Vielen Dank!
Gershom
4
@GershomMaes AUTH_USER_MODEL in settings.py und dem anderen Code in Ihren Ansichten oder wo immer Sie das Benutzermodell verwenden, sind Sie willkommen: D
Victor Castillo Torres
Arbeitete, sehr geschätzt!
Gershom
Wenn Sie nach diesen Informationen in den Dokumenten suchen
gmagno
2
Wahrscheinlich hat dies nichts mit dieser Frage zu tun, ich möchte nur eine Notiz über dieselbe Fehlermeldung. In meinem Fall in Django 3.0.4 habe ich contrib.auth.forms.UserCreationForm von .UserChangeForm verwendet und beide haben model = User in ihrer Meta-Klasse fest codiert (anstelle von = UserModel, das in dieser Datei gleich get_user_model () ist). Ich habe PR gemacht, aber ich weiß nicht, ob das Ersetzen von User-> UserModel korrekt ist und im Django-Projekt viele PRs warten.
Mirek
7

Für alle anderen, die auf dieses Problem stoßen könnten, habe ich es auch gelöst, indem ich dies einfach auf forms.py getan habe:

Fügen Sie dies oben in der Datei forms.py hinzu

from .models import YourCustomUser

und fügen Sie dies dann Ihrem forms.py CustomUserFormular hinzu:

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)

GROSSE ANMERKUNGEN, ACHTUNG :

  1. Dieser Code hat für meinen Fall funktioniert. Ich habe eine Ansicht zum Anmelden von Benutzern. Ich hatte hier ein Problem und habe es gelöst. Ich habe es nicht zum Anmelden von Benutzern ausprobiert.

  2. Das include = ()Teil ist erforderlich, oder Sie können hinzufügen exclude = (), aber Sie müssen eines haben

nur weil
quelle
Achtung : Der docs Zustand , dass Sie verwenden sollen , settings.AUTH_USER_MODELoder get_user_model()anstelle dieser Methode. Ich bin mir nicht sicher, ob dies nur eine Konvention ist oder ob Sicherheitsbedenken bestehen.
Elrond unterstützt Monica
5

Wichtiger Vorbehalt zum Aktualisieren der oben genannten Lösungen ... Wenn Sie mit dieser Art von Problem konfrontiert sind, haben Sie wahrscheinlich verschiedene Lösungen im Internet ausprobiert, in denen Sie aufgefordert werden AUTH_USER_MODEL = users.CustomUser, settings.pyden folgenden Code zu views.py forms.pyjeder anderen aufrufenden Datei hinzuzufügen und anschließend hinzuzufügen User:

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

Und dann kratzen Sie sich am Kopf, wenn Sie den Fehler erhalten:

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

Immer Userwenn Ihr Code auf Folgendes verweist :

User.objects.get()

Weil Sie wissen, dass Sie objects = UserManager()Ihre benutzerdefinierte Benutzerklasse bereits eingegeben haben (dies UserManagerist der Name Ihres benutzerdefinierten Managers, der erweitert wird BaseUserManager).

Wie sich herausstellt:

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

Ist NICHT gleichbedeutend mit:

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

Vielleicht nicht intuitiv, aber es stellt sich heraus, dass eine User = get_user_model()einmalige Ausführung in Python zum Zeitpunkt des Imports nicht dazu führt, Userdass sie über nachfolgende Aufrufe hinweg definiert wird (dh sie wird nicht Userzu einer Art "Konstante", die Sie erwarten könnten, wenn Sie ' Sie stammen aus einem C / C ++ - Hintergrund, dh, die Ausführung von User = get_user_model()erfolgt zum Zeitpunkt des Imports, wird jedoch vor dem anschließenden Aufruf der Klasse oder Funktion / Methode in dieser Datei de-referenziert.

Zusammenfassend lässt sich sagen, dass in allen Dateien, die auf die UserKlasse verweisen (z. B. Funktionen oder Variablen wie User.objects.get() User.objects.all() User.DoesNotExistetc ... aufrufen ):

# 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...

Hoffe das hilft anderen etwas Zeit zu sparen ...

Janus
quelle
0

Alle oben genannten Lösungen haben in meinem Fall nicht funktioniert. Wenn Sie Django Version 3.1 verwenden, gibt es eine andere Lösung für Sie:

Kommentieren Sie in auth / forms Zeile 10 aus und ändern Sie das Modell in Zeile 104 und 153 in Ihr definiertes Modell.

Afrikan_patriot
quelle