Менеджер недоступний; Користувача було замінено на "pet.Person"


80

Я використовую за замовчуванням модель користувача в django досить глибоко, і я усвідомлюю, що якщо мені потрібно буде її вдосконалити, мені доведеться створити власну користувацьку модель користувача в django 1.5.

Я створив власну користувацьку модель і маю функцію, яка дозволяє користувачам входити в систему. Я думаю, що моя користувацька модель користувача несумісна з моєю функцією, оскільки це не дозволило б мені зробити request.user. Як я можу це виправити, щоб я міг знову використовувати request.user?

погляди

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

моделі

 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

Відповіді:


163

Проблема в тому, що Userпосилається на, django.contrib.auth.models.Userі тепер ви отримали Custom User pet.Personприпущення, що маєте вsettings.py

AUTH_USER_MODEL = "pet.Person"

Ви повинні визначити Userз Custom Userмоделлю , і ви можете зробити це з get_user_modelу верхній частині файлу , в якому ви використовуєтеUser

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

тепер ви зможете використовувати Custom Userмодель, і проблема була виправлена.


Привіт, схоже, це вирішить мою проблему - мені було цікаво, в який файл повинен входити цей код? Дякую!
Герші

4
@GershomMaes AUTH_USER_MODEL всередині settings.py та інший код у ваших поданнях або де б ви не використовували модель користувача, ласкаво просимо: D
Віктор Кастільо Торрес

Працювали, дуже цінували!
Герші

Якщо ви шукаєте цю інформацію в документах: docs.djangoproject.com/en/2.2/topics/auth/customizing/…
gmagno

2
Можливо, у цьому немає нічого з цим запитанням, я просто хочу зазначити про те саме повідомлення про помилку. У моєму випадку в Django 3.0.4 я використовував contrib.auth.forms.UserCreationForm .UserChangeForm, і обидва вони мають model = User, закодований у своєму класі Meta (замість = UserModel, який у цьому файлі дорівнює get_user_model ()). Я зробив PR, але не знаю, чи правильна заміна User-> UserModel, а в проекті Django багато PR.
mirek

8

Для всіх, хто може зіткнутися з цією проблемою, я також вирішив її, просто зробивши це на form.py:

додати це у верхній частині файлу forms.py

from .models import YourCustomUser

а потім додайте це у свою forms.py CustomUserформу:

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)

ВЕЛИКІ ПРИМІТКИ, УВАГА :

  1. Цей код працював для мого випадку. У мене є подання для реєстрації користувачів, у мене тут була проблема, і я її вирішив, не пробував для входу користувачів.

  2. include = ()Частина потрібно, або ви можете додати exclude = (), але ви повинні мати один


1
Попередження : У документах зазначено, що вам слід використовувати цей метод settings.AUTH_USER_MODELабо get_user_model()замість нього. Я не впевнений, що це лише конвенція чи є проблеми з безпекою.
Елронд підтримує Моніку

6

Важливе застереження , щоб оновити вищевказані рішення ... Якщо ви зіткнулися з такою проблемою, ви , ймовірно , пробували різні рішення навколо мережі , що розповідають вам , щоб додати AUTH_USER_MODEL = users.CustomUserдо settings.pyі потім додати наступний код views.py forms.pyі будь-який інший файл , який викликає User:

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

І тоді ви чухаєте голову, коли отримуєте помилку:

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

Будь-коли посилання на ваш код, Userтакі як:

User.objects.get()

Тому що ви знаєте, що вже ввели objects = UserManager()свій користувацький клас користувача ( UserManagerце ім'я вашого користувацького менеджера, яке розширюється BaseUserManager).

Ну, як виявляється робити:

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

НЕ еквівалентно:

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

Можливо, не інтуїтивно зрозуміле, але виявляється, що в python, виконуючи User = get_user_model()один раз під час імпорту, це не призводить до Userтого, що воно визначається для наступних викликів (тобто воно не перетворюється Userна "константу", яку ви можете очікувати, якщо ви " що походить з фону C / C ++; це означає, що виконання User = get_user_model()виконується під час імпорту, але потім відміняється посилання перед подальшим викликом до класу або функції / методу у цьому файлі).

Отже, підсумовуючи, у всіх файлах, що посилаються на Userклас (наприклад, виклик функцій або змінних, таких як User.objects.get() User.objects.all() User.DoesNotExistetc ...):

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

Сподіваюся, це допоможе заощадити іншим трохи часу ...


0

Всі наведені вище рішення не працювали в моєму випадку. Якщо ви використовуєте Django версії 3.1, для вас є інше рішення:

У розділі auth / forms прокоментуйте рядок 10 і змініть модель у рядках 104 та 153 на визначену модель.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.