menu

Junjielee Blog

在平凡中坚持前行,总会遇见不凡的自己

Django middleware(中间件)介绍

据说Django中间件是Django比较出名的部分,那什么是中间件呢?

对于Django来说,请求到返回的流程大概是这样子:

# 如果没有渲染页面,则直接返回Response
Browser -> Web服务器 -> Wsgi -> Url路由 -> View函数 -> 渲染template -> Response

其中间件就是在这部分流程中间,插入一些功能,可以理解为钩子,将中间件函数挂在流程上。那么在哪一步骤可以插入功能呢?看下图就懂了

Browser -> Web服务器 -> Wsgi -> Url路由 -> View函数 -> 渲染template -> Response
                             |         |     |     |
                       process_request |     |     |
                               process_view  |     |
                                process_exception  |
                            process_template_response, process_response
  • process_request: 在路由之前执行
  • process_view:在执行view之前
  • process_exception:如果view函数报错,则执行
  • process_template_response: 如果有渲染页面,则在view后执行
  • process_response:在view后,process_template_response后执行

Django已经提供了一些官方的Middleware给我们使用,例如看配置文件也知道了:

'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',

包括session、auth权限认证,message通知等等,详细可以查看官方文档

自定义Middleware

创建一个类:实现process_request or process_view or process_exception or process_template_response or process_response方法,然后将这个类加入到 settings.MIDDLEWARE列表里

例如如果你需要做一个IP限制(假设Nginx没实现,需要在Django实现),可以这么写:

class IPLimtMiddleware(object):

    def process_request(self, request):
        if request.META.has_key('HTTP_X_FORWARDED_FOR'):
            ip =  request.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = request.META['REMOTE_ADDR']

        if ip == "192.168.1.1":
            return HttpResponse('<h1>你好</h1>')
        request.META['ip'] = ip

然后在settings文件里,MIDDLEWARE变量添加path.IPLimitMiddleware

Middleware执行方式

参考源码,Django会在启动的时候,加载所有Middlewares,按照顺序,分别将所有Middlewares分类存放到列表里。例如,将所有包含 process_request方法执的中间件,存入 process_request列表里,然后执行完所有 process_request中间件,再到process_views ...

Django的Middleware非常方便我们添加一些通用的功能,以及对于请求和返回的控制和操作

参考