本文主要是介绍【Django2.0学习笔记】31.自定义用户模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 31、自定义用户模型
- 1、拓展方法
- 1、继承Django的用户模型
- 2、新的模型拓展关联User
- 2、继承Django用户模型
- 3、继承的方法优缺点
- 4、新的模型拓展
- 5、拓展的方法优缺点
31、自定义用户模型
我们上节课在导航栏加了登录、注册和用户个人信息,在个人信息这里的个人资料,我们可能需要昵称这个信息,但我们这里没有昵称,因为系统自带的用户模型里没有这个字段,我们要想办法给它加一个这个字段
1、拓展方法
1、继承Django的用户模型
2、新的模型拓展关联User
2、继承Django用户模型
- 方法:
1)自定义模型继承AbstractUser
2)配置settings的AUTH_USER_MODEL - 使用:
外键关联settings.AUTH_USER_MODEL
用get_user_model的方法获取User模型
我们点开一个views.py文件,里面引用User的代码行from django.contrib.auth.models import User
,我们在django文件夹里找到这个文件查看
views.py中引用的User,就来源于这个地方,它本身继承了AbstractUser这个类,AbstractUser里面有username、first_name、last_name、email、is_staff(允不允许用户登录admin界面)、is_active(标注一下是不是激活状态)等这些字段。这里我们就演示下怎么去继承和使用(这里我们不打算使用第一种方法继续后面的课程,所以这里我们把mysite_env下面的mysite项目文件夹先复制一份出来mysite_test,进行演示第一种方法,另外这里面可能会有一个问题会导致数据库需要重新建立,所以要先做好备份工作)
我们打开mysite_test这个文件夹,在mysite_test/user下新建models.py,写入如下代码:
from django.db import models
from django.contrib.auth.models import AbstractUserclass User(AbstractUser):nickname = models.CharField(max_length=20, default='')class Meta(AbstractUser.Meta):pass
然后在settings.py中多加一行代码AUTH_USER_MODEL = 'user.User'
(指定用户模型是哪个模型)
这样的话,我们就完成了方法的定义,接下来就是使用这个方法
我们之前使用是引用 auth.models
里面的User
模型,现在已经被我们改了,就引用不到了。我们要删掉这一行引用,然后加一行引用from django.conf import settings
,然后在代码中对应的使用到User的地方改为settings.AUTH_USER_MODEL
(全局查找,对应修改所有引用到User的文件)
注意,其中user/forms.py和views.py中引用User是不一样的,这里是直接去使用这个模型,而不是作为外键。这里就需要改为from django.contrib.auth import get_user_model
,然后添加一个代码User = get_user_model()
,在后面用到User的代码部分就不用进行修改了
改完之后,我们进行入mysite_test的虚拟环境,迁移数据库,
这里就会有个报错
它之前的user已经关联到之前Django自带的user了,改动没有用,那么这种情况我们需要做一个处理,要把blog、comment、likes、read_statistics、user等这些app下的migrations里面的迁移文件全部删除掉,然后数据库db.sqlite3先不删,先改名为db1.sqlite3。然后重新生成 应用迁移文件,创新创建了数据库,没有报错,
然后我们在创建缓存表python manage.py createcachetable
,创建超级管理员python manage.py createsupeuser
。输入用户名 test,密码abc123456,跟之前设置一样,邮箱暂时不写。创建完毕之后,我们启动服务
刷新页面,登录进入后台,我们发现没有“用户”,这是因为我们自定义的用户没有进行注册写到admin后台管理这里,我们可以尝试加一个,参考django/contrib/auth/admin.py中的UserAdmin部分的代码。在user目录下新建admin.py,写入如下代码:
user/admin.py:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_modelUser = get_user_model()@admin.register(User)
class UserAdmin(BaseUserAdmin):pass
再刷新后台页面,可以看到有“用户”了
我们点进去查看
可以看到没有昵称那个字段,我们需要加进去,那要怎么加呢,我们可以看到,我们继承了UserAdmin这个类,在目录django.contrib.auth.admin
里面可以看到,它显示字段这一块的代码,参考这一段代码,我们修改user/admin.py如下:
刷新页面,可以看到有Nickname这个字段了,我们可以把它改成中文的,修改user/models.py如下:
这样,我们就可以写入昵称了,比如写入昵称“张张张”保存,保存之后可以看到外面没有显示出来,这里我们也可以改动一下,在admin.py中加入list_display
,修改user/admin.py如下:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_model
from django.utils.translation import gettext, gettext_lazy as _ # 翻译User = get_user_model()@admin.register(User)
class UserAdmin(BaseUserAdmin):fieldsets = ((None, {'fields': ('username', 'password')}),(_('Personal info'), {'fields': ('nickname', 'email')}),(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser','groups', 'user_permissions')}),(_('Important dates'), {'fields': ('last_login', 'date_joined')}),)list_display = ('username', 'email', 'nickname', 'is_staff', 'is_active', 'is_superuser')
刷新页面:
3、继承的方法优缺点
- 优点:
1)自定义强
2)没有不必要的字段(需要继承AbstractBaseUser) - 优点:
2)需要删库重来或者要项目一开始就使用
2)配置admin麻烦
4、新的模型拓展
- 方法:
1)创建自定义模型
2)外键关联User - 使用:
1)直接使用即可
现在我们重新回到mysite文件夹,在user中新建models.py,写入如下代码,新建一个模型Profile:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\mysite\models.py
from django.db import models
from django.contrib.auth.models import Userclass Profile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE) # 创建外键,与User关联。一对一字段,一个Profile对应一个User,一个User对应一个Profilenickname = models.CharField(max_length=20)def __str__(self): # 显示字符串return '<Profile: %s for %s>' % (self.nickname, self.user.username)
我们可以在user下新加一个admin.py文件,让它在后台管理界面显示出来,代码如下:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\mysite\admin.py
from django.contrib import admin
from .models import Profile@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):list_display = ('user', 'nickname')
接着启动mysite的虚拟环境,迁移应用数据库,启动服务,
刷新后台页面,我们可以看到有Profile,我们可手动添加数据并保存,这里如果我们再给同一个user添加Nickname,可以看到会出现错误提示“具有User的Profile已存在”,因为是一对一的,是不允许一条User对应多条记录的,所以我们外键类型才会选OneToOneField
这个字段(我们也可以查看django官方文档查看这个字段)
另外它这里也提供了怎么样在那个用户模型里面看到Nickname相关信息的方法,我们可以复制粘贴到user/admin.py中
重启服务,刷新后台,点击“用户”——点进去具体用户,可以看到,就多了昵称这一字段信息(这里也可以改成中文,修改models.py即可)
那么怎么样让如下这个页面也显示出昵称呢
我们可以在mysite/admin.py的UserAdmin里加一个list_display,覆盖一下
5、拓展的方法优缺点
- 优点:
1)使用方便
2)不用删库重来影响整体构架 - 缺点:
1)存在不必要的字段
2)对比继承的方法,查询速度稍微慢一丁点
最后我们来完善几个地方
(1)在登录后的右侧导航栏“个人资料”、“退出”那里,如果能多加一个跳到后台页面的选择,会方便一些
修改templates/base.html:
(2)先点击下导航栏的“登录”,再点击下“注册”,再点“登录”,登录成功之后会回跳到注册页面(同理,先点击下导航栏的“注册”,再点击下“登录”,再点“注册”,注册成功之后会回跳到登录页面),也就是会跳转到进入该页面之前的那个页面(注意看每次的url里面的from参数值)
如果我们是已经登录成功了,那么最好是不要让它再跳转回注册或者登录页面。这里我们可以模仿user/templates/user/user_info.html里面有个逻辑判断:已经登录就让它跳转到首页的代码,
修改login.html和register.html如下:
这样的话,登录成功之后,就会直接跳转到首页,而不是跳转到上一个页面。
这篇关于【Django2.0学习笔记】31.自定义用户模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!