一:Auth模块
1.什么是Auth模块?
Auth模块是Django自带的用户认证模块:
1 2 3 4 |
1.我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。 2.Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统–auth,它默认使用 auth_user 表来存储用户数据。 |
2.Auth模块作用
1 2 3 4 5 |
1 django提供的用户认证,创建,修改密码。。。用户相关操作 2 不需要创建用户表了,默认带了 3 插入数据(创建用户): python3 manage.py createsuperuser |
二:引入Auth模块
1.其实我们在创建好一个Django项目之后直接执行数据库迁移命令会自动生成很多表
1 2 3 4 |
列如: django_session auth_user |
2.django在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且还必须是管理员用户才能进入
3.创建超级用户(管理员)
1 2 |
python3 manage.py createsuperuser |
4.Django自带的admin后端管理
5.需求
- 依赖于auth_user表完成用户相关的所有功能
6.方法总结
问题(1.表如何获取 2.密码如何比对 存储表中密码是密文的)
三:解决方法(auth模块)
1 2 3 4 5 6 |
1.自动查询auth_user标签 2.自动给密码加密再比对 该方法注意事项: 括号内必须同时传入用户名和密码 不能只传用户名(一步就帮你筛选出用户对象) |
1.比对用户名和密码是否正确
1 2 3 4 5 6 7 8 9 10 |
# 导入auth模块 from django.contrib import auth # 1.比对用户名和密码是否正确 user_obj = auth.authenticate(request,username=username,password=password) # 括号内必须同时传入用户名和密码 print(user_obj) # 用户对象 jason 数据不符合则返回None print(user_obj.username) # jason print(user_obj.password) # 密文 |
2.保存用户状态
1 2 3 |
auth.login(request,user_obj) # 类似于request.session[key] = user_obj # 主要执行了该方法 你就可以在任何地方通过request.user获取到当前登陆的用户对象 |
3.获取当前登陆用户
1 2 3 |
print(request.user) # 用户对象 没登陆拿到的是匿名用户 AnonymousUser # 自动去django_session里面查找对应的用户对象给你封装到request.user中 |
4.判断当前用户是否登陆
1 2 |
request.user.is_authenticated() |
5.校验用户是否登陆装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from django.contrib.auth.decorators import login_required # 局部配置 @login_required(login_url='/login/') # 全局配置settings内 LOGIN_URL = '/login/' 1.如果局部和全局都有 该听谁的? 局部 > 全局 2.局部和全局哪个好呢? 全局的好处在于无需重复写代码 但是跳转的页面却很单一 局部的好处在于不同的视图函数在用户没有登陆的情况下可以跳转到不同的页面 |
6.比对原密码
1 2 3 4 |
# 校验老密码 check_password 原密码 # 返回值就是一个布尔值 is_right = request.user.check_password(old_password) # 自动加密比对密码 |
7.修改密码
1 2 3 4 5 6 7 |
# 判断原密码正常为True 原密码错误为False if is_right: # 修改密码 request.user.set_password(new_password) # 添入新密码(仅仅修改对象的属性) request.user.save() # 操作数据库 return redirect('/login/') |
8.注销
1 2 |
auth.logout(request) # 类似于 request.session.flush() |
9.注册
1 2 3 4 5 6 7 8 9 |
1.操作auth_user表写入数据 User.objects.create(username=username,password=password) # 写入数据 不能用create 密码没有加密处理 2.创建普通用户 # 加密处理 User.objects.create_user(username=username,password=password) 3.创建超级用户(了解):使用代码创建超级用户 邮箱是必填的 而用命令创建则可以不填 User.objects.create_superuser(username=username,email='123@qq.com',password=password) |
10.整体代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
###### 10.整体代码 ```python # views.py from django.shortcuts import render, HttpResponse, redirect from django.contrib import auth #登陆 def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 去用户表中效验数据 # 1.表如何获取 # 2.密码如何比对 存储表中密码是密文的 # 使用auth模块 user_obj = auth.authenticate(request, username=username, password=password) # 判断当前用户是否存在 if user_obj: # 保存用户状态(利用auth操作session表) auth.login(request, user_obj) # 类似于request.session[key] = user_obj 将用户对象存到session表内 return render(request, 'login.html') from django.contrib.auth.decorators import login_required # 主页 # 局部配置: 用户没有登陆跳转到login_user后面指定的网址 # @login_required(login_url='/login/') # 优先级 局部 大于 全局 @login_required def home(request): print(request.user) # 用户对象 没登陆拿到的是匿名用户 AnonymousUser # 判断用户是否登陆 print(request.user.is_authenticated()) # 自动去django_session里面查找对应的用户对象给你封装到request.user中 return HttpResponse('home') @login_required def index(request): return HttpResponse('index') # 修改 @login_required def set_password(request): if request.method == 'POST': old_password = request.POST.get('old_password') new_password = request.POST.get('new_password') confirm_password = request.POST.get('confirm_password') # 校验两次密码是否一致 if new_password == confirm_password: # 校验老密码 check_password 原密码 # 返回值就是一个布尔值 is_right = request.user.check_password(old_password) # 自动加密比对密码 # 判断原密码正常为True 原密码错误为False if is_right: # 修改密码 request.user.set_password(new_password) # 添入新密码(仅仅修改对象的属性) request.user.save() # 操作数据库 return redirect('/login/') return render(request, 'set_password.html', locals()) # 注销 @login_required def logout(request): auth.logout(request) # 类似于 request.session.flush() return redirect('/login/') from django.contrib.auth.models import User # 注册 @login_required def register(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 操作auth_user表写入数据 # User.objects.create(username=username, password=password) # 写入数据 不能使用create 密码没有加密处理 # 创建普通用户 加密处理 User.objects.create_user(username=username, password=password) return render(request, 'registration.html') # settings.py # 全局配置 没有登陆跳转到指定页面 LOGIN_URL = '/login/' # urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), # 1.登陆功能 url(r'^login/', views.login), # 2.主页(校验用户是否登陆) url(r'^home/', views.home), url(r'^index/', views.index), # 3.修改密码 url(r'^set_password/', views.set_password), # 4.注销功能 url(r'^logout/', views.logout), # 5.注册功能 url(r'^register/', views.register), ] # login.html <form action="" method="post"> {% csrf_token %} <p>username: <input type="text" name="username"></p> <p>password: <input type="text" name="password"></p> <input type="submit"> </form> # registration.html <form action="" method="post"> {% csrf_token %} <h1>注册</h1> <p>username: <input type="text" name="username"></p> <p>password: <input type="text" name="password"></p> <input type="submit"> </form> # set_password.html <form action="" method="post"> {% csrf_token %} {# disabled 只能看 不能改 #} <p>username: <input type="text" name="username" disabled value="{{ request.user.username }}"></p> <p>old_password: <input type="text" name="old_password"></p> <p>new_password: <input type="text" name="new_password"></p> <p>confirm_password: <input type="text" name="confirm_password"></p> <input type="submit"> </form> |
四:如何扩展auth_user表
1.需求:
- 扩展auth_user字段
2.如果继承了AbstractUser会如何?
1 2 3 |
1.那么在执行数据库迁移命令的时候auth_user表就不会再创建出来了 2.而userInfo表中出现auth_user所有的字段外加自己扩展的字段 |
3.优点
1 2 |
1.这么做的好处在于你能够直接点击你自己的表更加快速的完成操作及扩展 |
4.实现该方法前提:
1 2 3 4 5 6 7 8 |
1.在继承之前没有执行过数据库迁移命令(auth_user没有被创建) 如果当前库已经创建了,那么你就重新换一个库 2.继承的类里面不要覆盖AbstractUser里面的字段名 表里面有的字段都不要动,只扩展额外字段即可 3.需要在配置文件中告诉Django你要用UserInfo替代auth_user AUTH_USER_MODEL = 'app01.UserInfo' 直接应用名点表名即可 |
5.扩展auth_user字段实践
- models
1 2 3 4 5 6 7 8 9 |
from django.db import models from django.contrib.auth.models import User, AbstractUser # User继承了AbstractUser, auth_user内的字段来自AbstractUser类 # 1.利用面向对象的继承 class UserInfo(AbstractUser): phone = models.BigIntegerField() |
6.实现扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
1.__init__.py # 切换到pymysql import pymysql pymysql.install_as_MySQLdb() 2.配置文件settings更改数据库mysql DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'day00', 'USER': 'root', 'PASSWORD': '123', 'HOST': '127.0.0.1', 'PORT': 3306, 'CHARSET': 'utf8', } } 3.auth表配置 AUTH_USER_MODEL = 'app01.UserInfo' 4.数据库迁移 makemigrations # 同步 migrate |
7.总结:
1 2 3 |
你如果自己写表替代了auth_user那么 auth模块的功能还是照常使用,参考的表页由原来的auth_user变成了UserInfo |