摘要:想要进行全局判断不知道如何处理,请求的时候连路由都不希望让其进行匹配,

想把某个用户拉入黑名单?这就是我们的门卫-中间件!

 

中间件

用于在全局范围内改变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)

 

posted on 2019-06-18 20:00  谢Rain  阅读(1080)  评论(0编辑  收藏  举报