96

我在 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
4

6 回答 6

191

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

于 2013-07-26T06:08:56.050 回答
10

对于可能遇到此问题的其他任何人,我也通过简单地在 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 = (),但您必须有一个

于 2018-12-27T17:44:14.327 回答
9

更新上述解决方案的重要警告......如果您遇到此类问题,您可能已经尝试了网络上的各种解决方案,告诉您添加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你可能期望的“常量”,如果你' re 来自 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...

希望这有助于节省其他人一些时间......

于 2019-06-19T15:29:06.327 回答
4

forms.py

# change
from django.contrib.auth.models import User

# to
from django.contrib.auth import get_user_model

然后在顶部添加以下代码

User = get_user_model()
于 2021-05-14T08:02:35.333 回答
0

我的问题是我只会使用 Django Python 的 Rest_Api。那是我的项目设置:

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'

管理员.py

from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

设置.py

AUTH_USER_MODEL = 'mealSheetApi.User'
于 2022-03-05T07:53:29.107 回答
-4

上面提供的所有解决方案都不适用于我的情况。如果您使用 Django 3.1 版,还有另一种解决方案:

在 auth/forms 中,注释掉第 10 行并将第 104 和 153 行中的模型更改为您定义的模型。

于 2020-10-08T09:02:54.230 回答