经理不可用;用户已被替换为“ pet.Person”


76

我一直在使用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

Answers:


158

问题是 Userdjango.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模型,并且问题已得到解决。


您好,这看起来可以解决我的问题-我想知道代码应该放入哪个文件?谢谢!
Gershom 2015年

4
@GershomMaes settings.py中的AUTH_USER_MODEL以及您视图中或使用用户模型的任何地方的其他代码,我们都很欢迎:D
Victor Castillo Torres

工作,非常感谢!
Gershom 2015年


2
可能与此问题无关,我只想记录有关相同的错误消息。就我在Django 3.0.4中的情况而言,我使用了.UserChangeForm的contrib.auth.forms.UserCreationForm,并且它们都在其Meta类中硬编码了model = User(而不是在此文件中等于get_user_model()的= UserModel)。我进行了PR,但我不知道替换User-> UserModel是否正确,并且在Django项目中有许多PR在等待。
Mirek

7

对于可能遇到此问题的其他人,我也只需在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)

大注意事项

  1. 这段代码适用于我的情况。我有一个注册用户的视图,这里有一个问题,我已经解决了,我没有尝试过用于登录用户。

  2. include = ()零件是必需的,或者您可以添加exclude = (),但是您必须有一个


警告文档指出您应使用settings.AUTH_USER_MODELget_user_model()代替此方法。我不确定这只是一个约定,还是存在安全隐患。
Elrond

5

更新上述解决方案的重要警告...如果您遇到此类问题,则可能已经在网络上尝试了各种解决方案,告诉您添加AUTH_USER_MODEL = users.CustomUsersettings.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行中的模型更改为您定义的模型。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.