Менеджер недоступен; Пользователь был заменен на 'pet.Person'
Я довольно часто использую модель пользователя по умолчанию в 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
8 ответов
Проблема в том, что 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
модель и проблема была исправлена.
Для всех, кто сталкивался с этой проблемой, я также решил ее, просто выполнив это на forms.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)
БОЛЬШИЕ ЗАМЕЧАНИЯ, ВНИМАНИЕ:
Этот код работал для моего случая. У меня есть вид для регистрации пользователей, у меня была проблема, и я решил ее, я не пробовал ее для входа в систему пользователей.
include = ()
часть требуется, или вы можете добавитьexclude = ()
, но вы должны иметь один
Важное предостережение для обновления вышеуказанных решений... Если вы столкнулись с такой проблемой, вы, вероятно, пробовали различные решения в Интернете, предлагающие добавить 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.DoesNotExist
так далее...):
# 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...
Надеюсь, это поможет сэкономить время другим...
В forms.py Изменение с django.contrib.auth.models импортировать пользователя на
из djangi.contrib.auth import get_user_model
Затем добавьте следующий код вверху
Пользователь = get_user_model()
Кроме того, в моем случае я напрямую включил UserCreationForm в свой файл views.py вместо импорта из файла forms.py.
Моя проблема в том, что я буду использовать Rest_Api только из Django Python. Это мой проект
mealSheetAI
setting.py
mealSheetApi
admin.py
models.py
модели.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
USERNAME_FIELD = 'email'
admin.py
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
settings.py
AUTH_USER_MODEL = 'mealSheetApi.User'
В моем случае проблема была связана с настройкой form.py моего приложения.
Я нашел причину ошибки и добавил ее. См. комментарий в коде:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import get_user_model
class RegisterForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model() #### I included this,VERY IMPORTANT
fields = ("email",)
Изначально он отсутствовал, отсюда и причина ошибки.
Если вы заметили, мой класс RegisterForm расширяет UserCreationForm.
А UserCreation расширяет базовый класс BaseUserCreationForm .
BaseUserCreationForm, в свою очередь, имеет подкласс Meta с моделью = User.
По умолчанию эта модель указывает на django.contrib.auth.models.User .
это не то, что вам нужно, поскольку вы уже используете собственный класс.
Все приведенные выше решения в моем случае не сработали. Если вы используете Django версии 3.1, для вас есть другое решение:
В auth/forms закомментируйте строку 10 и измените модель в строках 104 и 153 на вашу определенную модель.