Django User 模块之 AbstractUser 扩展详解
作者:种子选手 发布时间:2022-03-31 17:23:28
最近在写博客,刚好写到用户注册注销模块,觉得这一方面还是挺有趣的。当尝试掀开 Django 的源代码时一切 API 就不会变得那么摸不着。顺着读Django 的各模块源码,我们可以更灵活地更改代码以实现自己想要的功能。
现在,思考一个问题,主需求是实现博客中用户的注册登录登出功能。如果只满足于用户注册时只登记其邮箱或是用户名,Django 自带的 User 模块既可以实现。但实际上,一个普遍的要求是注册用户应该能够修改自己的头像信息,邮箱信息,昵称信息等其他更灵活的需求。
可以先看一下 Django User 模块的源码
class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model.
Username, password and email are required. Other fields are optional.
"""
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
注意:如果你的是 Anaconda 管理,可以在路径 C:\Users\User\Anaconda3\Lib\site-packages\django\contrib\auth\models.py 查看
Django 中的 User 模块实际上继承了 AbstractUser 模块,AbstractUser 模块下有 :
username
first_name
last_name
email
date_joined
…
你可以看出,User 模块继承了 AbstractUser 抽象基类,而仅仅只是继承了,并没有对 AbstractUser 进行任何扩展。所以,对于一个需要更多需求的 User 模块信息来说,我们可以继承 AbstractUser 并根据自己的需求进行扩展。
现在,我们对用户属性添加一些需求,比如支持用户修改头像、支持用户昵称、qq、wechat 以及网站链接等。
class User(AbstractUser):
nickname = models.CharField(max_length=30, blank=True, null=True, verbose_name='昵称')
qq = models.CharField(max_length=20, blank=True, null=True, verbose_name='QQ号码')
url = models.URLField(max_length=100, blank=True, null=True, verbose_name='个人网页地址')
avatar = ProcessedImageField(upload_to='avatar',
default='avatar/default.png', verbose_name='头像')
class Meta:
verbose_name = '用户'
verbose_name_plural = verbose_name
ordering = ['-id']
def __str__(self):
return self.username
我们给自定义的用户模块增加 nickname(昵称), qq, url(网站链接),avatar(头像)属性。
注意:为了让 Django 能够识别使用自定义的用户模型,必须要在 settings.py 中设置自定义模块位置,如在 settings.py 上添加
AUTH_USER_MODEL = 'blog.user'
其中,blog 为你对应的应用 app 信息,user 为 blog 应用下的 user 模块,在这里 blog 和 user 大小写无关。
如果在你现在执行数据库迁移命令,可能会出现 blog 不存在 user 模块 的提示,而无法重新进行数据迁移。
ValueError: The field account.EmailAddress.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field admin.LogEntry.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field blog.Article.author was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field easy_comment.Comment.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field easy_comment.Like.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field notifications.Notification.recipient was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field online_status.OnlineStatus.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field socialaccount.SocialAccount.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
所以,如果之前是使用例如 AUTH_USER_MODEL = auth.user 的用户模型,并重新将其自定义为 AUTH_USER_MODEL = blog.user 请删掉 migrations 目录下的所有文件 以及数据库文件。
删除之后,重新进行数据库的迁移
$ python manage.py makemigrations myapp
$ python manage.py migrate
这个时候,所使用的用户即为自定义后的用户了。
File "C:\Users\Micky\Anaconda3\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Micky\Anaconda3\lib\site-packages\django\db\backends\sqlite3\base.py", line 303, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: blog_user
这里可以在模板中指定数据库 db_table = 'user'
补充知识:Django学习笔记——内置用户类AbstractUser与内置认证校验系统
内置用户类AbstractUser
我们在之前讲过了model模型的作用和父类的作用,这次介绍的内置用户类AbstractUser就是Django内置的一个关于用户操作的类,它极大地方便了我们对model模型中对User用户类的设计。而所谓内置用户类的本质也就是一个封装好的父类,所以使用起来是相当的方便。
#导入AbstractUser类
from django.contrib.auth.models import AbstractUser
#直接继承就可以了,如果有需要就向寻常model一样写字段就可以
class User(AbstractUser):
pass
我们通过查看AbstractUser的源码可以知道它设有几个字段
#用户名
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
#名
first_name = models.CharField(_('first name'), max_length=30, blank=True)
#姓
last_name = models.CharField(_('last name'), max_length=150, blank=True)
#邮箱
email = models.EmailField(_('email address'), blank=True)
#权限
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'),
)
#激活
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
#日期
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
内置认证校验系统
django自带的用户认证校验系统较为简单,主要就是认证用户名密码的正确与否
首先要在settings里面配置
#使用自带的认证系统
AUTH_USER_MODEL = "user.User"
这是配合自带的用户类AbstractUser一起使用的
通常使用在类视图中的post方法校验用户登录等操作
在view中的具体代码如下
class LoginView(View):
def get(self,request):
#逻辑代码
return render(request,'login.html')
def post(self,request):
# 获取前端传递过来的用户名和密码
username = request.POST.get('username')
pwd = request.POST.get('pwd')
record = request.POST.get('record')
# 进行数据校验
if not all([username,pwd]):
return HttpResponse('数据输入不完整')
# 验证用户名和密码是否正确
user = authenticate(username=username,password=pwd)
return render(request,''index.html')
主要就是其中的user = authenticate(username=username,password=pwd)
两个参数都是拿到前端用户输入的信息
来源:https://blog.csdn.net/qq_36148847/article/details/82599180
猜你喜欢
- 有个帖子写的检查全角的 <script> fun
- 当py文件中引用了库face_recognition但是python中没有安装这个库的时候,就会出现No module named '
- 很久没有跟其他人做重构思想方面的交流了,可能大家都觉得不太好意思讨论,特别是“分离”的思想这么基础的话题,拿出来说怕会被“笑话”。做为页面重
- 自动签到的python脚本源码新建一个python文件,checkin.py,保存到电脑上某个位置,我这里保存到的是E:\pyproject
- 一。安装python1.到python官网下载安装包注意:班级同学们请到班级资料下载安装包,可以不用到网上下载。点击导航栏download-
- 本文实例形式讲解了Python3的条件与循环控制语句及其用法,是学习Python所必须掌握的重要知识点,现共享给大家供大家参考。具体如下:一
- 1.python爬虫浏览器伪装#导入urllib.request模块import urllib.request#设置请求头headers=(
- 1,不用第三方库# coding: utf-8import loggingBLACK, RED, GREEN, YELLOW, BLUE,
- 本文实例讲述了JS实现合并json对象的方法。分享给大家供大家参考,具体如下:一、问题:求json对象合并的方法var a ={"
- 尝试安装server[justin@xen20-vm04 "]$ rpm -ivh MySQL-server-5.1.51-1.g
- With语句是什么?有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个
- 一、模块模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数,因此一个py文件就可以看成一个模块。如果这个py文件的文件名为mo
- 前言:随机数模块实现了各种分布的伪随机数生成器。对于整数,从范围中有统一的选择。 对于序列,存在随机元素的统一选择、用于生成列表的随机排列的
- 字符串遍历>>> a_str = "hello itcast">>> for cha
- 本文实例讲述了Python使用pickle模块报错EOFError Ran out of input的解决方法。分享给大家供大家参考,具体如
- 本文实例讲述了Python堆排序原理与实现方法。分享给大家供大家参考,具体如下:在这里要事先说明一下我也是新手,很多东西我了解不是很深入,写
- Python 网络请求模块 urllib 、requestsPython 给人的印象是抓取网页非常方便,提供这种生产力的,主要依靠的就是 u
- 摘 要:本文讨论了Visual Basic应用程序访问SQL Server数据库的几种常用的方法,分别说明了每种方法的内部机理并给出了每种方
- 序Python易用,但用好却不易,其中比较头疼的就是包管理和Python不同版本的问题,特别是当你使用Windows的时候。为了解决这些问题
- 本文实例分析了Python自定义进程池。分享给大家供大家参考,具体如下:代码说明一切:#encoding=utf-8#author: wal