Django学习笔记之中间件和上下文处理器

Django中间件(Middleware

是一个轻量级、底层的“插件”系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出.

激活中间件

需要把它添加到Django配置文件中的MIDDLEWARE_CLASSES元组中.

自定义中间件

每个中间件组件是一个独立的Python类,可以定义下面方法中的一个或多个

  • _init _:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件
  • process_request(request):执行视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
  • process_view(request, view_func, view_args, view_kwargs):调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
  • process_template_response(request, response):在视图刚好执行完毕之后被调用,在每个请求上调用,返回实现了render方法的响应对象
  • process_response(request, response):所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象
  • process_exception(request,response,exception):当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象
例子:

settings.py同级目录下创建mymiddleware.py文件,定义类MyException,实现自定义异常process_exception方法

#---------mymiddleware.py------------

from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin

# F1
class MyException(MiddlewareMixin):
    def process_exception(self,request,exception):
        return HttpResponse(exception)

# F2
from ts22.models import UserModel
class UserMiddleware(MiddlewareMixin):
    def __init(self,get_response):
        self.get_response = get_response

    def __call__(self,request):
        # request到达view之前执行的代码
        username = request.session.get('username','未登录')
        user = UserModel.objects.filter(username=username).first()
        if user and not hasattr(request,'myuser'):
            setattr(request,'myuser',user)
        response = self.get_response(request)
        # response到达用户浏览器之前执行的代码
        return response

# 这样写之后,view函数里面就可以跟之前省去一部分内容了

将类MyException注册到settings.py中间件中

#---------setting.py------------

MIDDLEWARE_CLASSES = (
      ...
    'test.mymiddleware.MyException',
    'test.myMiddleware.UserMiddleware',
)

# 注test11是项目名。

模板上下文处理器(context processor)

settings.py中,包含了当前使用的上下文处理器。他的作用是可以给每一个response都提供自己想要添加的参数。

settings.py->TEMPLATES->OPTIONS->context_processors中使用的上下文处理器的作用:

django.template.context_processors.debug:增加一个debug变量。
django.template.context_processors.request:增加一个request的变量。
django.contrib.auth.context_processors.auth:增加了一个user的变量。
django.contrib.messages.context_processors.messages: 增加了一个messages的变量。
自定义上下文处理器:

中间件有点类似给request添加属性,而上下文处理器有点类似给模板添加属性的意思。一个是向上,一个是向下。

settings.py同级目录下创建mycontextprocessor.py文件,定义一个myuser的函数

#-------------mycontextprocessor.py------------
from music.models import UserModel
def myuser(request):
    username = request.session.get('username', '未登录')
    user = UserModel.objects.filter(username=username).first()
    if user:
        return {'myuser': user.username}
    else:
        return {}

# 注意:1.必须传入request作为参数  2.必须返回一个字典

将我们定义的上下文处理器放到settings.py->TEMPLATES->OPTIONS->context_processors中。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'test11.mycontextprocessor.myuser',
            ],
        },
    },
]