Django框架之-----用户认证auth模块
我们在开发一个网站时, 无法避免的需要设计网站的用户系统, 此时我们需要实现包括用户注册,登录,认证,注销,修改密码等功能,把这些事全部写一遍也挺麻烦的,
Django作为一个完美主义的终极框架, 也当然会为用户想到这些痛点,它内置了强大的用户认证系统,默认使用auth_user表来存储用户数据
auth模块的使用
常用内置方法
authenticate() 用户认证,一般校验用户和密码,严谨一点多添加一个邮箱
login() 任证后的登录对象
logout() 退出登录
is_authenticated() 判断用户是否通过认证
login_requierd() 登录认证装饰器
create_user() 创建普通用户
create_superuser() 创建管理员用户
check_password() 校验密码
set_password() 设置、修改 密码
User对象的属性,
is_staff:用户是否拥有网站的管理权限
is_active:用户是有拥有登录本站权限, 设置为0,用户则不能登录网站,一般为管理员设置的选项
-
authenticate()
提供了用户认证功能,即验证用户名、密码、邮箱等是否正确,一般只验证username、password两个关键字段。如果成功,返回一个User对象
authenticate()会在该User对象上设置一个属性来表示后端已经认证了该用户, 且该用户信息在后续视图函数中直接使用即可,无需再次登录。
用法:
user=authenticate(username="username",password="password")
-
login()
该函数接收一个HttpRequest对象, 以及一个经过认证后的User对象
该函数实现一个用户登录功能,它本质上会在后端为该用户生成相关session数据 保存到数据库中
创建用户
python manage.py createsuperuser
两个模块一般结合使用,如下:
导入模块
from django.contrib.auth import authenticate,login
def user_login(request):
if request.method == "GET":
return render(request,'login.html')
else:
name = request.POST.get("name")
pwd = request.POST.get("password")
# 校验用户名和密码,
user = authenticate(username=name,password=pwd)
if user:
# 通过后添加到全局, 后期所有地方都可以调用到这个对象
login(request,user)
return redirect('base')
else:
return render(request,'login.html')
成功后定向到这个页面(首页)
def base(request):
return render(request,'base.html')
先创建模板login.html和base.html文件。
<form action="" method="post">
{% csrf_token %}
<p><input type="text" name="name"></p>
<p><input type="password" name="password"></p>
<p><input type="submit" value="提交"></p>
</form>
-
logout使用
该函数接收一个HttpRequest对象, 无返回值
当调用改函数时, 当前请求的session信息会被全部删除, 既是用户没有登录,也可操作删除用户数据,当用户数据不存在时也不会报错。这就是Django的强大之处。
用法很简单,只需要 logout(request) 即可
前提是在登录状态下操作如下方法:
视图函数 from django.contrib.auth import logout def user_logout(request): logout(request) return redirect('base') 模板中 在主页添加a标签即可,点击a标签触发logout路由,执行函数 base中 <body> <h1>base</h1> <a href="{% url 'logout' %}">点击退出</a> </body> 路由 path("logout/", views.user_logout, name='logout')
-
is_authenticated() 判断用户是否登录状态
即其他函数中需要判断用户是否登录后进行访问, 如订单页面需要登录后才能查看个人订单, 否则无法生成订单页面。在request中
用法:
request.user.is_authenticated
视图函数中 def order(request): # 判断是否已经登录状态, 没有登录返回登录页面给用户等, 记录用户跳转页面,登录成功后跳转回用户访问页面 if request.user.is_authenticated: return render(request,'order.html') else: return redirect('login') 路由 path("order/", views.order,name="order") 用在模板中,登录后显示登录,没有登录显示去登录 {% if request.user.is_authenticated %} {{ request.user.username }} 登录了 {% else %} <a href="/login/">去登录</a> {% endif %}
-
login_requierd() 装饰器使用
在需要登录才能访问的函数上添加这装饰器即可,简单一批
from django.contrib.auth.decorators import login_required @login_required(login_url='登录失败后定向地址') def order(request): pass 注:若用户没有登录,则会跳转到django默认的登录路径/accounts/login/ 并传递当前url地址过去, 让登录成功后定向到传过去的地址, 指定后则则会定向到指定地址。
-
create_user、create_superuser 方法
创建用户,auth提供的一个创建新用户符方法, 需要提供必要的参数(username,password、邮箱等参数)
用法:User类
from django.contrib.auth.models import User def create_user(request): User.objects.create_user(username="用户名",password="密码") # 密码存到数据库是密文 创建超级管理员方法一样,调用create_superuser即可
-
check_password() 使用
auth提供的一个检查密码是否正确方法, 一般不用,因为网站中提示的是
账号或密码错误,不会指定的提示密码错误(了解即可)
。正确密码返回True,否则返回False。用法:
先获取用户,校验密码是否正确,进一步校验入下 user = User.objects.filter(username=name).first() 判断密码是否正确 flag=user.check_password(password) if flag: ...
-
set_password() 重置密码模块 (重点)
auth提供了一个修改密码的方法, 接收要设置的新密码,操作如下
需要注意的是: 设置完成后一定要调用save方法
先获取到用户对象 def change_password(request): if request.method == 'GET': return render(request, 'change_pwd.html') else: old_pwd = request.POST.get('old_pwd') new_pwd = request.POST.get('new_pwd') re_new_pwd = request.POST.get('re_new_pwd') if request.user.check_password(old_pwd): # 密码正确再修改 request.user.set_password(new_pwd) # 记住保存(****) request.user.save() 重点哈!!! return redirect('/login/') else: return HttpResponse('原来密码错误') HTML代码就不放这里了 都哪些写入提交form表单 OK!
到这里已经学完auth模块的所有常用方法, 感觉不过如此, 继续前行吧!!
User对象的属性
is_staff : 用户是否拥有网站的管理权限,是否可以登录到后台管理
is_superuser:是否是超级管理员(如果is_staff=1,可以任意增删查改任何表数据)
is_active : 是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录(三次密码输入错误禁用用户)
扩展默认的auth_user表
这内置的认证系统那么好用, 但是auth_user表字段都是固定的那几个, 在项目无法直接使用, 里面的字段远远无法满足对项目的需求,在此。
聪明的你可能会想到新建另外一张表通过一对一和内置的auth_user表关联,这样虽然满足了需求,但也很麻烦, 这样
我们可以通过继承内置的AbstractUser类, 来定义一个自己的Model类
这样既能根据项目需求灵活的设计用户表,又能后使用Django强大的认证系统, 岂不美哉。
1 内置的auth_user表,要加字段,加不了,扩展该表
-方式一:一对一
-方式二,通过继承
# 方式二:通过继承,一定要记住再setting中配置
## 重点:使用这种方式,一开始就要用
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# id=models.AutoField(primary_key=True)
# username = models.CharField(max_length=128)
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
注意: 一定要在配置模块中添加如下常量配置(重点)
## setting.py中
AUTH_USER_MODEL = "app01.User"
-
选型方案(项目已经开发到一半,如下方法很好解决眉睫)
1 备份--删库---》重新创建出数据库 2 所有app的数据迁移记录删除migrations下除了__init__.py都删除 3 (重要)去源码中删除auth和admin 这俩app的migrations下除了__init__.py都删除 4 数据迁移,同步到数据库 5 备份的数据,恢复回去
AUTH_USER_MODEL = “app01.User”
-
选型方案(项目已经开发到一半,如下方法很好解决眉睫)
1 备份--删库---》重新创建出数据库 2 所有app的数据迁移记录删除migrations下除了__init__.py都删除 3 (重要)去源码中删除auth和admin 这俩app的migrations下除了__init__.py都删除 4 数据迁移,同步到数据库 5 备份的数据,恢复回去
完!!