Django中间件工作流程及写法实例代码
熟悉web开发的同学对hook钩子肯定不陌生,通过钩子可以方便的实现一些触发和回调,并且做一些过滤和拦截。 django中的中间件(middleware)就是类似钩子的一种存在。下面我们来介绍一下,并且给出一些实例。 1、Middleware的工作流程我盗了一个图,看网上很多人用这个图,来源已经追不明白了。简单声明一下,这个图不是我的。看着图我们分析一下: 1)django的请求相应流程:HttpRequest -> RequestMiddleware -> view function -> ResponseMiddleware -> HttpResponse 可以看到一个请求到响应的过程,中间夹着两个middleware流程,请求中间件和响应中间件。 也就是说,django提供了一种机制,在:
支持嵌入钩子。 这种钩子的特点:
2) django的middleware包含四个钩子函数:process_request/process_view/process_response/process_exception
而插入middleware的过程是在settings.py中配置,如下默认配置,我只截取了两个中间件:SessionMiddleware和CommonMiddleware。 MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware',... ) 我们简单看一下 import time from importlib import import_module from django.conf import settings from django.utils.cache import patch_vary_headers from django.utils.http import cookie_date class SessionMiddleware(object): def __init__(self): engine = import_module(settings.SESSION_ENGINE) self.SessionStore = engine.SessionStore def process_request(self,request): session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME,None) request.session = self.SessionStore(session_key) def process_response(self,request,response): """ If request.session was modified,or if the configuration is to save the session every time,save the changes and set a session cookie or delete the session cookie if the session has been emptied. """ try: accessed = request.session.accessed modified = request.session.modified empty = request.session.is_empty() except AttributeError: pass else: # First check if we need to delete this cookie. # The session should be deleted only if the session is entirely empty if settings.SESSION_COOKIE_NAME in request.COOKIES and empty: response.delete_cookie(settings.SESSION_COOKIE_NAME) else: if accessed: patch_vary_headers(response,('Cookie',)) if modified or settings.SESSION_SAVE_EVERY_REQUEST: if request.session.get_expire_at_browser_close(): max_age = None expires = None else: max_age = request.session.get_expiry_age() expires_time = time.time() + max_age expires = cookie_date(expires_time) # Save the session data and refresh the client cookie. # Skip session save for 500 responses,refs #3881. if response.status_code != 500: request.session.save() response.set_cookie(settings.SESSION_COOKIE_NAME,request.session.session_key,max_age=max_age,expires=expires,domain=settings.SESSION_COOKIE_DOMAIN,path=settings.SESSION_COOKIE_PATH,secure=settings.SESSION_COOKIE_SECURE or None,httponly=settings.SESSION_COOKIE_HTTPONLY or None) return response 可以看到在 我们就以这个例子说明一下一个请求的执行过程。我们假设场景是这样的: 1)从上而下配置了两个Middleware(注意顺序):SessionMiddleware和CommonMiddleware 2)每个Middleware中的四个钩子函数齐全 执行顺序应该是这样的: 1、HttpRequest 2、SessionMiddleware process_request 3、SessionMiddleware process_view 4、CommonMiddleware process_request 5、CommonMiddleware process_view 6、view 7、CommonMiddleware process_response 8、CommonMiddleware process_exception(如有必要) 9、SessionMiddleware process_response 10、SessionMiddleware process_exception(如有必要) 11、HttpResponse 2、Middleware的写法Middleware的写法很简单:1)实现一个类,继承object就行; 2)重写其中的四个钩子函数就可以了。 这里要着重说一个常用的功能。 拦截器/过滤器(filter)一般来说,每一个请求都要经过 1)None 2)HttpResponse 对象 如果返回None,请求流程继续执行,也就是继续进入其他的Middleware或者钩子函数。 如果返回HttpResponse对象,那么就直接返回到页面。通过这个功能我们可以做黑名单。 给一个例子: 就是统计pv # -*- coding:utf-8 -*- from datetime import datetime from data_monitor.utils.dbmanager import MysqlManager from data_monitor.common.constant import MYSQL_JOBS as mysql_config class RequestHookMiddleware(object): def process_request(self,request): try: username = request.COOKIES.get('username') uri = request.path timestamp = str(datetime.now()) db_obj = MysqlManager( mysql_config.get('host'),mysql_config.get('port'),mysql_config.get('db'),mysql_config.get('user'),mysql_config.get('password'),format=True,) field_str = 'username,uri,timestamp' value_str = '"%s","%s","%s"' % (username,timestamp) db_obj.insert('pv',field_str,value_str) db_obj.close() return except Exception,ex: return 总结以上就是本文关于Django中间件工作流程及写法实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持! 您可能感兴趣的文章:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |