摘要:想要进行全局判断不知道如何处理,请求的时候连路由都不希望让其进行匹配,
想把某个用户拉入黑名单?这就是我们的门卫-中间件!
中间件
用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。
怎么自定义中间件
步骤1:在任意地方定义类 继承 MiddlewareMixin
步骤2:实现方法
步骤3:注册中间件
比如
在app01.models 创建一个自定义中间件
注册中间件
就会依次从上往下执行每个中间件里的process_request方法
中间件里的每个方法介绍
process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
中间件方法
1.process_request(self,request)
执行视图函数之前,遇到None走下一个中间件,一直是None就进入urls,
每个中间件都是同一个
2.process_response(self, request, response)
返回必须是HttpResponse对象,拿到的是一个传递过来的response和request
3.process_view(self, request, view_func, view_args, view_kwargs)
路由匹配成功之后 执行视图函数之前
view_func:是一个马上执行的视图函数
view_args:给视图的位置参数
view_kwargs:给视图的关键字参数
4. process_exception(self, request, exception)
视图函数中出现异常了才执行
exception:视图函数残生的Exception对象
5.process_template_response(self, request, response)
,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。
大致
Django生命周期
csrf中间件(防止跨站伪造请求)
CSRF会自动鉴别这个网站的Form表单是否是我传递给你的CSRF_token
{%csrf_token%}
<form action="" method="post"> {% csrf_token %} <input type="text" name="username"> <input type="text" name="password"> <input type="submit" > </form>
前端里就会生成一个token,每次都不一致
调整CSRF认证的灵活性
打开csrf中间件后需要全部进行认证
如果想某个视图函数可以不用验证,就需要导入免认证装饰器
from django.views.decorators.csrf import csrf_exempt,csrf_protect
开启情况下 禁用csrf认证
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def index(request): return render(request,"register.html")
关闭情况下 进行Csrf认证
# 局部使用 @csrf_protect def login(request): pass
如果是CBV呢?
from django.utils.decorators import method_decorator @method_decorator(csrf_exempt,name='dispatch') # 第一种 class Csrf_Token(View): @method_decorator(csrf_exempt) # 第二种 def dispatch(self,request,*args,**kwargs): res = super().dispatch(request,*args,**kwargs) return res @method_decorator(csrf_exempt) # 这里这么写不行!!! def get(self,request): pass def post(self,request): pass
Auth认证
Django自带的用户认证,无需我们手动的去判断,当我们进行数据库迁移命令时会生成一个
这个就是,您可以自己露一脸里面有什么 这里不做讲解
创建一条超级用户
或者自己去插入
from django.contrib.auth.models import User User.objects.create() # 不能用这个,因为密码是明文 User.objects.createuser(username='用户名',password='密码',email='邮箱',...) # 创建普通用户 User.objects.createsuperuser(username='用户名',password='密码',email='邮箱',...) # 创建超级用户
Auth的增删改查
1.查询数据
authenticate(字段=“值”,字段2=“值2”) #查找数据 成功返回一个user_obj
def index(request): if request.method=="POST": reg=auth.authenticate(request,username=request.POST.get("username"),password=request.POST.get("password")) print(reg,type(reg)) #xzq <class 'django.contrib.auth.models.User'>
2.登陆用户
接受一个request和认证过的对象,为后台生成session数据
全局就可以通过request.user拿到这个对象,否则拿到的是个匿名用户
3.怎么判断是匿名还是认证过的用户?
request.user.authenticate
4.注销
auth.logout(request)
两端删除session数据request.session.flush()
5.添加一个装饰器,让其没有认证就自动转登陆
不写:
配置login_url
但是提交url是这样的,提交后不会跳转
6.需要验证的函数太多了怎么办?都写url?
可以放在全局配置里 setting.py
LOGIN_URL = '/login/' # 既可以局部配置,也可以全局配置
login_url就可以不指定
7.验证某个user对象是否通过了校验
is_authenticated()
def my_view(request): if not request.user.is_authenticated(): return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
8.修改密码,验证密码
auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。
密码正确返回True,否则返回False。
request.user.check_password(pwd) # 为什么不直接获取查,因为前端用户输入的是明文数据库密文 request.user.set_password(pwd) request.user.save() # 修改密码一定要记得保存
自定义Auth表
第二种方式需要在setting.py中指定我自己创建的表
AUTH_USER_MODEL = "app名.models里面对应的模型表名"
rom django.contrib.auth.model import User #找到这django_auth这张表 #一对一关系 class UserDetail(models.Models): phone = models.CharField(max_length=11) user = models.OnoToOneField(to=User) 面向对象的继承 from django.contrib.auth.models import User,AbstractUser class UserInfo(AbstractUser): phone = models.CharField(max_length=32)