Менеджер недоступен; Пользователь был заменен на "pet.Person"
Я использую модель пользователя по умолчанию в django для довольно abit, и я понимаю, что если мне нужно еще больше ее улучшить, мне придется создать свою собственную пользовательскую модель в 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
Ответы
Ответ 1
Проблема в том, что User
ссылается на django.contrib.auth.models.User
и теперь у вас есть Custom User
pet.Person
что у вас есть в settings.py
AUTH_USER_MODEL = "pet.Person"
вы должны определить User
с Custom User
моделью Custom User
и вы можете сделать это с помощью get_user_model
в верхней части файла, в котором вы используете User
from django.contrib.auth import get_user_model
User = get_user_model()
теперь вы сможете использовать Custom User
модель Custom User
и проблема устранена.
Ответ 2
Для всех, кто сталкивался с этой проблемой, я также решил ее, просто выполнив это на 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 =()
, но у вас должна быть одна
Ответ 3
Важное предупреждение для обновления вышеуказанных решений... Если вы сталкиваетесь с подобной проблемой, вы, вероятно, пробовали различные решения в Интернете, предлагая вам добавить 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 = get_user_model()
перед последующим 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...
Надеюсь, это поможет сэкономить время другим...