Django分析之Middleware中间件

写了几周的脚本,今天终于开始接触web框架了~学习Python的web框架,那么Django就几乎是必修课了,这次的工作是先打打下手,主要的任务是在setting中添加版本号,在渲染静态css,js的路径时附带版本号,例如“example.v1124.css”,然后再在request请求中祛除掉版本号。为什么要这么做呢?因为这样做的话在前端输出静态文件的路径就会加上就会加上版本号,这样当开发出新的静态文件的时候,客户端就会强制刷新本地的缓存,为了达到这个目的就要首先要在settings文件中配置,这样就可以每次修改的时候直接从settings读取版本号了,下面是大致的处理流程,各位自己感受一下吧~

Django分析之Middleware中间件

好了,那么我们就开始一步步的完成吧~首先在settings文件中定义好一个版本号的变量。

#Static file version number
STATIC_VERSION = 'v1124'

然后就是在你要使用版本号的app中的views文件中取到这个变量并赋值给需要渲染的模板中了。

#要想在settings文件中取到变量就要先导入模块
from django.conf import settings #在settings配置文件中取得静态文件版本号
version = settings.STATIC_VERSION #下面这个函数是例子.....
def index(request):
template = loader.get_template('base/base_index.html')
#将取得的静态文件版本号传入到模板中
context = Context({'version':version})
return HttpResponse(template.render(context))

这样就可以在HTML文件中这样写静态文件路径了。

<link rel="stylesheet" type="text/css" href="/youappname/static/css/css.{{version}}.css">
<script language="javascript" type="text/javascript" src="/youappname/static/js/script.{{version}}.js"></script>

到这一步,当你打开浏览器后台的时候你就会发现你的路径就会改变了,但是这个时候当你再刷新的时候就会出现静态文件找不到的问题了,为什么会这样呢?因为这个时候的浏览器会继续按照新的路径去请求静态文件,但是你会发现你静态文件的物理地址其实是没有改变过的,所以这时候你请求的是新的地址,自然也就取不到了,那么我们该怎么办呢?

下面就是我们的主角Middleware出场了!那什么是Middleware呢?文档上说是中间件,可能不好理解,那么其实就是Javaweb框架中Struts2中的拦截器,无论是作用还是原理都是如出一辙的,那么这样一等价的话就很好理解Django中的Middleware了,既然是拦截器那么能做的就不仅仅是过滤一个静态文件版本号这么简单咯,查看了文档之后发现它还有很多很多实用的功能,那么都能哪些方法呢?

process_request  接受request之后确定所执行的view之前

process_view  确定了所要执行的view之后 view真正执行之前

process_response   view 执行之后

process_exception(self, request, exception)  view抛出异常

通过我们继承实现上面的一个或者多个方法就可以实现我们想要的功能了,那么它的处理流程呢?自然也是和拦截器一样了。

Django分析之Middleware中间件

为什么要注意这个处理流程呢?因为这个流程会影响我们在settings文件中配置我们自己的Middleware顺序,其实在settings文件中我们的配置顺序就是它执行的顺序了,那么说到底该如何安装Middleware呢?

首先我们先要在settings文件中配置好我们的Middleware文件路径

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
#下面的这个地址就是我们自己的中间件文件了
'youappname.pyname.calssname',
)

这样我们就已经安装好了自己的中间件了,那下面就可以拦截下所有的request请求了,现在我们该在中间件中处理我们的业务逻辑了

#coding=utf-8
import urllib,pdb,re
from django.template import RequestContext
from django.shortcuts import render_to_response class middlewareVersion(object):
def process_request(self, request):
#判断如果url请求中有今天文件的请求,那么就拦截下来
if request.path_info.startswith('/youappname/static/'):
#得到path路径,使用正则表达式将版本号过滤掉
request.path_info = re.sub(r'\.v\d+','',request.path_info)

因为我的版本号是以v开头,后面是数字,所以用正则将这样的字符串替换成空。

现在按照之前流程图里面的我们是不是就完成了呢?显然不是嘛~仅仅这样做的话你会发现你的Middleware并没有起作用,我们用pdb断点调试发现,其实我们并没有捕获到静态文件的request请求,为什么会这样呢?因为是一个系统app捣的鬼!

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
#就是下面的这个app
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)

如果我们没有额外配置static路径的话,系统会默认将所有静态文件的请求发给staticfiles来处理,所以我们要将这个app静止掉,这样就可以完美的接收请求了,鉴于我百度了很多方法都没有给出路由文件的配置方法,这样会导致结果会不正确,所以我就把路由中的配置方法贴出来了。

static_dir = os.path.join(os.path.dirname(__file__),'../youappname/static')

urlpatterns += patterns('',
(r'^youappname/static/(?P<path>.*)$','django.views.static.serve',{'document_root':static_dir}),
)

这样就应该不会再出现什么大的问题了。完美收官!!!

今天的工作繁琐而又多,为了实现这个小功能我也是看了又看试了又试,果然英语不好真是硬伤额T.T…..今晚就到这了,下次有机会再写一些其他小功能吧。

上一篇:MySQL Windows版安装详解


下一篇:未能从程序集“System.ServiceModel,xxx”中加载类型“System.ServiceModel.Activation.HttpModule”。