Django分析之Middleware中間件


      寫了幾周的腳本,今天終於開始接觸web框架了~學習Python的web框架,那么Django就幾乎是必修課了,這次的工作是先打打下手,主要的任務是在setting中添加版本號,在渲染靜態css,js的路徑時附帶版本號,例如“example.v1124.css”,然后再在request請求中祛除掉版本號。為什么要這么做呢?因為這樣做的話在前端輸出靜態文件的路徑就會加上就會加上版本號,這樣當開發出新的靜態文件的時候,客戶端就會強制刷新本地的緩存,為了達到這個目的就要首先要在settings文件中配置,這樣就可以每次修改的時候直接從settings讀取版本號了,下面是大致的處理流程,各位自己感受一下吧~

QQ圖片20141124220758

  好了,那么我們就開始一步步的完成吧~首先在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拋出異常

通過我們繼承實現上面的一個或者多個方法就可以實現我們想要的功能了,那么它的處理流程呢?自然也是和攔截器一樣了。

QQ截圖20141124223029

      為什么要注意這個處理流程呢?因為這個流程會影響我們在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…..今晚就到這了,下次有機會再寫一些其他小功能吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM