上一節咱們介紹了緩存來減輕服務器的負擔,這裏的有條件的視圖處理也從必定程度上減輕了服務器的負擔,在正式介紹以前,先來看兩個概念:Last-Modified和ETagweb
知道了這兩個概念以後,咱們應該知道這兩個概念的做用了吧,也大概知道咱們接下來要講解的是什麼啦。沒錯,就是,django中如何使用Last-Modified和ETag這兩個概念呢django
Last-Modified和ETag在django中是兩個函數,前者返回一個日期類型數據,後者返回一個值(ETag值),這兩個函數能夠做爲參數傳遞給django.views.decorators.http.condition這個裝飾器,裝飾器原型是瀏覽器
這是一個使用的簡單例子緩存
def latest_entry(request, blog_id): return Entry.objects.filter(blog=blog_id).latest("published").published from django.views.decorators.http import condition @condition(last_modified_func=latest_entry) def front_page(request, blog_id): ...
在django.views.decorators.http.condition文件裏還提供了另外兩個裝飾器,可使得只須要提供一個參數便可,看源碼很容易懂:安全
def etag(etag_func): return condition(etag_func=etag_func) def last_modified(last_modified_func): return condition(last_modified_func=last_modified_func)
說完了Last-Modified和ETag,咱們繼續說一下服務器
web應用安全的黃金法則是:永遠不要相信從不受信任來源的數據。但有時候咱們只能從不受信任的媒介獲取或者發送數據,或者不受信任的媒介更具吸引力,好比咱們確保咱們的數據必定是安全的,而且不受信任的媒介比受信任媒介要快捷甚至便宜的多。加密簽名的值一旦被篡改就會被檢測到,這是咱們能確保數據安全的共識。下面是幾個加密簽名應用的例子:cookie
django提供了一個底層的用來加密數據的API和一個高層的用來設置和讀取加密cookies的API數據結構
用django-admin.py startproject命令生成的項目自帶一個自動隨機生成的SECRET_KEY,注意不要泄露這個key函數
django的加密方法源代碼位於django\core目錄下的signing.py文件,能夠具體去看看,下面是一些基本的用法:編碼
>>> from django.conf import settings >>> settings.configure() >>> from django.core.signing import Signer >>> signer = Signer() >>> value = signer.sign("qiweijie") >>> value 'qiweijie:lVrPb11e1K9K_DcxnMGNYk8t2aQ' >>> original = signer.unsign(value) >>> original u'qiweijie'
salt是「鹽,調味劑」的意思,若是你不想每次對同一字符加密的結果都同樣,那麼你能夠是用調味劑參數調劑一下,哈哈,看示例:
>>> signer = Signer() >>> signer.sign('My string') 'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w' >>> signer = Signer(salt='extra') >>> signer.sign('My string') 'My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw' >>> signer.unsign('My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw') u'My string'
TimestampSigner是Signer的子類,添加了一個加密的時間戳給值。這容許你能夠確保一個加密的數據是在一個給定的時間內建立的
>>> from django.core.signing import TimestampSigner >>> signer = TimestampSigner() >>> value = signer.sign('hello') >>> value 'hello:1NMg5H:oPVuCqlJWmChm1rA2lyTUtelC-c' >>> signer.unsign(value) u'hello' >>> signer.unsign(value, max_age=10) ... SignatureExpired: Signature age 15.5289158821 > 10 seconds >>> signer.unsign(value, max_age=20) u'hello'
列表,元組和字典,若是你直接使用上述的方法,最後獲得的是一個字符串而不是原來的數據類型:
>>> dic = {1:2} >>> sd=signer.sign(dic) >>> signer.unsign(sd) u'{1: 2}'
若是你想保護這些數據類型,請使用dumps和loads方法,它們都位於django.core.signing模塊裏面
>>> from django.core import signing >>> value = signing.dumps({"foo": "bar"}) >>> value 'eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI' >>> signing.loads(value) {'foo': 'bar'}