第25天拍霜,Django之緩存嘱丢、序列化、信號(hào)

目錄

一祠饺、緩存
    1. 配置
        1.1 開(kāi)發(fā)調(diào)試
        1.2 內(nèi)存
        1.3 文件
        1.4 數(shù)據(jù)庫(kù)
        1.5 Memcache緩存(python-memcached模塊)
        1.6 Memcache緩存(pylibmc模塊)
    2. 緩存應(yīng)用
        2.1 站點(diǎn)級(jí)緩存
        2.2 單個(gè)視圖緩存
        2.3 模板片段緩存
二越驻、序列化
    1、serializers
    2吠裆、json.dumps
三伐谈、信號(hào)
    1. Django內(nèi)置信號(hào)

一、緩存

由于Django是動(dòng)態(tài)網(wǎng)站试疙,所有每次請(qǐng)求均會(huì)去數(shù)據(jù)進(jìn)行相應(yīng)的操作诵棵,當(dāng)程序訪(fǎng)問(wèn)量大時(shí),耗時(shí)必然會(huì)更加明顯祝旷,最簡(jiǎn)單解決方式是使用:緩存履澳,緩存將一個(gè)某個(gè)views的返回值保存至內(nèi)存或者memcache中,5分鐘內(nèi)再有人來(lái)訪(fǎng)問(wèn)時(shí)怀跛,則不再去執(zhí)行view中的操作距贷,而是直接從內(nèi)存或者Redis中之前緩存的內(nèi)容拿到,并返回吻谋。

Django中提供了6種緩存方式:

  • 開(kāi)發(fā)調(diào)試
  • 內(nèi)存
  • 文件
  • 數(shù)據(jù)庫(kù)
  • Memcache緩存(python-memcached模塊)
  • Memcache緩存(pylibmc模塊忠蝗,只是與上面換了個(gè)模塊而已)

1. 配置

1.1 開(kāi)發(fā)調(diào)試

    # 此為開(kāi)始調(diào)試用,實(shí)際內(nèi)部不做任何操作
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
                'TIMEOUT': 300,                                               # 緩存超時(shí)時(shí)間(默認(rèn)300漓拾,None表示永不過(guò)期阁最,0表示立即過(guò)期)
                'OPTIONS':{
                    'MAX_ENTRIES': 300,                                       # 最大緩存?zhèn)€數(shù)(默認(rèn)300)
                    'CULL_FREQUENCY': 3,                                      # 緩存到達(dá)最大個(gè)數(shù)之后,剔除緩存?zhèn)€數(shù)的比例骇两,即:1/CULL_FREQUENCY(默認(rèn)3)
                },
                'KEY_PREFIX': '',                                             # 緩存key的前綴(默認(rèn)空)
                'VERSION': 1,                                                 # 緩存key的版本(默認(rèn)1)
                'KEY_FUNCTION' 函數(shù)名                                          # 生成key的函數(shù)(默認(rèn)函數(shù)會(huì)生成為:【前綴:版本:key】)
            }
        }


    # 自定義key
    def default_key_func(key, key_prefix, version):
        """
        Default function to generate keys.

        Constructs the key used by all other methods. By default it prepends
        the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
        function with custom key making behavior.
        """
        return '%s:%s:%s' % (key_prefix, version, key)

    def get_key_func(key_func):
        """
        Function to decide which key function to use.

        Defaults to ``default_key_func``.
        """
        if key_func is not None:
            if callable(key_func):
                return key_func
            else:
                return import_string(key_func)
        return default_key_func

注意:如果不需要自定義緩存的key速种,可以不用寫(xiě)KEY_PREFIX、VERSION低千、KEY_FUNCTION以及自定義key的函數(shù)配阵。

1.2 內(nèi)存

    # 此緩存將內(nèi)容保存至內(nèi)存的變量中
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'unique-snowflake',
            }
        }

    # 注:其他配置同開(kāi)發(fā)調(diào)試版本

1.3 文件

    # 此緩存將內(nèi)容保存至文件
    # 配置:

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
                'LOCATION': '/var/tmp/django_cache',
            }
        }
    # 注:其他配置同開(kāi)發(fā)調(diào)試版本

1.4 數(shù)據(jù)庫(kù)

    # 此緩存將內(nèi)容保存至數(shù)據(jù)庫(kù)

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 數(shù)據(jù)庫(kù)表
            }
        }

    # 注:執(zhí)行創(chuàng)建表命令 python manage.py createcachetable

使用數(shù)據(jù)庫(kù)緩存之前,你必須用這個(gè)命令來(lái)創(chuàng)建緩存表:

python manage.py createcachetable

1.5 Memcache緩存(python-memcached模塊)

Memcached有一個(gè)非常好的特點(diǎn)就是可以讓幾個(gè)服務(wù)的緩存共享示血。 這就意味著你可以在多臺(tái)機(jī)器上運(yùn)行Memcached服務(wù)棋傍,這些程序?qū)?huì)把這幾個(gè)機(jī)器當(dāng)做 同一個(gè) 緩存,從而不需要復(fù)制每個(gè)緩存的值在每個(gè)機(jī)器上难审。為了使用這個(gè)特性舍沙,把所有的服務(wù)地址放在LOCATION里面,用分號(hào)隔開(kāi)或者當(dāng)做一個(gè)list剔宪。

# 此緩存使用python-memcached模塊連接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': 'unix:/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

1.6 Memcache緩存(pylibmc模塊)

    # 此緩存使用pylibmc模塊連接memcache
    
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

2. 緩存應(yīng)用

緩存應(yīng)用分為三種模式:

  • 站點(diǎn)級(jí)緩存
  • 單個(gè)視圖緩存
  • 模板片段緩存

2.1 站點(diǎn)級(jí)緩存

一旦高速緩存設(shè)置拂铡,最簡(jiǎn)單的方法是使用緩存緩存整個(gè)網(wǎng)站壹无。

   使用中間件,經(jīng)過(guò)一系列的認(rèn)證等操作感帅,如果內(nèi)容在緩存中存在斗锭,則使用FetchFromCacheMiddleware獲取內(nèi)容并返回給用戶(hù),當(dāng)返回給用戶(hù)之前失球,判斷緩存中是否已經(jīng)存在岖是,如果不存在則UpdateCacheMiddleware會(huì)將緩存保存至緩存,從而實(shí)現(xiàn)全站緩存

MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
    # 其他中間件...
    'django.middleware.cache.FetchFromCacheMiddleware',
]


CACHE_MIDDLEWARE_ALIAS = ""      # 用于存儲(chǔ)的緩存的別名
CACHE_MIDDLEWARE_SECONDS = ""    # 每個(gè)page需要被緩存多少秒实苞。這個(gè)優(yōu)先級(jí)大于CACHES中的TIMEOUT參數(shù)豺撑。
CACHE_MIDDLEWARE_KEY_PREFIX = ""  # 如果緩存被使用相同Django安裝的多個(gè)網(wǎng)站所共享,那么把這個(gè)值設(shè)成當(dāng)前網(wǎng)站名黔牵,或其他能代表這個(gè)Django實(shí)例的唯一字符串聪轿,以避免key發(fā)生沖突。 如果你不在意的話(huà)可以設(shè)成空字符串猾浦。
    

注意: 'Update'中間件陆错,必須放在列表的開(kāi)始位置,而Fectch中間件金赦,必須放在最后音瓷。

2.2 單個(gè)視圖緩存

#方式一:
from django.views.decorators.cache import cache_page

cache_page(60 * 15)    # 60秒*15,也就是緩存15分鐘
def my_view(request):
    pass

#方式二:
from django.views.decorators.cache import cache_page

urlpatterns = [
    url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]

注意:cache_page接受一個(gè)參數(shù):timeout夹抗,秒為單位绳慎。在前例中,“my_view()”視圖的結(jié)果將被緩存 15 分鐘 (注意為了提高可讀性我們寫(xiě)了 60 * 15 . 60 * 15 等于 900 –也就是說(shuō)15分鐘等于60秒乘15.)

2.3 模板片段緩存

在模版文件中加入

# a. 引入TemplateTag

     {% load cache %}

# b. 使用緩存

     {% cache 5000 緩存key %}
         緩存內(nèi)容
     {% endcache %}

注意:5000是指緩存5000秒漠烧,緩存的key可以是自定義的字符串杏愤。

二、序列化

關(guān)于Django中的序列化主要應(yīng)用在將數(shù)據(jù)庫(kù)中檢索的數(shù)據(jù)返回給客戶(hù)端用戶(hù)沽甥,特別的Ajax請(qǐng)求一般返回的為Json格式。

1乏奥、serializers

from django.core import serializers
 
ret = models.BookType.objects.all()
 
data = serializers.serialize("json", ret)

2摆舟、json.dumps

import json
 
#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')
 
ret=list(ret)
 
result = json.dumps(ret)

由于json.dumps時(shí)無(wú)法處理datetime日期,所以可以通過(guò)自定義處理器來(lái)做擴(kuò)展邓了,如:

import json 
from datetime import date 
from datetime import datetime 
   
class JsonCustomEncoder(json.JSONEncoder): 
    
    def default(self, field): 
     
        if isinstance(field, datetime): 
            return o.strftime('%Y-%m-%d %H:%M:%S') 
        elif isinstance(field, date): 
            return o.strftime('%Y-%m-%d') 
        else: 
            return json.JSONEncoder.default(self, field) 
   
   
# ds = json.dumps(d, cls=JsonCustomEncoder) 

三恨诱、信號(hào)

Django中提供了“信號(hào)調(diào)度”,用于在框架執(zhí)行操作時(shí)解耦骗炉。通俗來(lái)講照宝,就是一些動(dòng)作發(fā)生的時(shí)候,信號(hào)允許特定的發(fā)送者去提醒一些接受者句葵。

1. Django內(nèi)置信號(hào)

Model signals
    pre_init                    # django的modal執(zhí)行其構(gòu)造方法前厕鹃,自動(dòng)觸發(fā)
    post_init                   # django的modal執(zhí)行其構(gòu)造方法后兢仰,自動(dòng)觸發(fā)
    pre_save                    # django的modal對(duì)象保存前,自動(dòng)觸發(fā)
    post_save                   # django的modal對(duì)象保存后剂碴,自動(dòng)觸發(fā)
    pre_delete                  # django的modal對(duì)象刪除前把将,自動(dòng)觸發(fā)
    post_delete                 # django的modal對(duì)象刪除后,自動(dòng)觸發(fā)
    m2m_changed                 # django的modal中使用m2m字段操作第三張表(add,remove,clear)前后忆矛,自動(dòng)觸發(fā)
    class_prepared              # 程序啟動(dòng)時(shí)察蹲,檢測(cè)已注冊(cè)的app中modal類(lèi),對(duì)于每一個(gè)類(lèi)催训,自動(dòng)觸發(fā)
Management signals
    pre_migrate                 # 執(zhí)行migrate命令前洽议,自動(dòng)觸發(fā)
    post_migrate                # 執(zhí)行migrate命令后,自動(dòng)觸發(fā)
Request/response signals
    request_started             # 請(qǐng)求到來(lái)前漫拭,自動(dòng)觸發(fā)
    request_finished            # 請(qǐng)求結(jié)束后亚兄,自動(dòng)觸發(fā)
    got_request_exception       # 請(qǐng)求異常后,自動(dòng)觸發(fā)
Test signals
    setting_changed             # 使用test測(cè)試修改配置文件時(shí)嫂侍,自動(dòng)觸發(fā)
    template_rendered           # 使用test測(cè)試渲染模板時(shí)儿捧,自動(dòng)觸發(fā)
Database Wrappers
    connection_created          # 創(chuàng)建數(shù)據(jù)庫(kù)連接時(shí),自動(dòng)觸發(fā)

對(duì)于Django內(nèi)置的信號(hào)挑宠,僅需注冊(cè)指定信號(hào)菲盾,當(dāng)程序執(zhí)行相應(yīng)操作時(shí),自動(dòng)觸發(fā)注冊(cè)函數(shù):

需要將觸發(fā)信號(hào)的代碼放在項(xiàng)目下同項(xiàng)目名稱(chēng)的目錄下的init.py中各淀,例如django項(xiàng)目名稱(chēng)為myblog懒鉴,則需要將下列代碼寫(xiě)至myblog/myblog/init.py中。

需求:當(dāng)對(duì)某個(gè)數(shù)據(jù)庫(kù)做寫(xiě)入操作時(shí)碎浇,就觸發(fā)某個(gè)函數(shù)的執(zhí)行临谱。

from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

from django.db.backends.signals import connection_created


def signal(sender,**kwargs):
    print('Django信號(hào)測(cè)試')
    print('sender: ',sender)
    print('kwargs: ',kwargs)

# 調(diào)用信號(hào)的connect方法,將自定義的函數(shù)當(dāng)作參數(shù)傳遞進(jìn)去
post_save.connect(signal)      # 當(dāng)對(duì)數(shù)據(jù)庫(kù)做保存操作時(shí)奴璃,就會(huì)觸發(fā)上述signal函數(shù)的執(zhí)行

注意:自定義的函數(shù)傳入一個(gè)位置參數(shù)sender悉默,它是觸發(fā)此函數(shù)執(zhí)行的某個(gè)模塊;kwargs內(nèi)容請(qǐng)看下面打印結(jié)果苟穆;

# 打印結(jié)果如下:
# Django信號(hào)測(cè)試
# sender:  <class 'blog.models.Blog'>
# kwargs:  {'update_fields': None, 'created': True, 'instance': <Blog: 我的python>, 'signal': <django.db.models.signals.ModelSignal object at 0x0000000002E00FD0>, 'using': 'default', 'raw': False}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抄课,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子雳旅,更是在濱河造成了極大的恐慌跟磨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攒盈,死亡現(xiàn)場(chǎng)離奇詭異抵拘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)型豁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)僵蛛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)尚蝌,“玉大人,你說(shuō)我怎么就攤上這事墩瞳⊥蘸” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵喉酌,是天一觀的道長(zhǎng)热凹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)泪电,這世上最難降的妖魔是什么般妙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮相速,結(jié)果婚禮上碟渺,老公的妹妹穿的比我還像新娘。我一直安慰自己突诬,他們只是感情好苫拍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著旺隙,像睡著了一般绒极。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔬捷,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天垄提,我揣著相機(jī)與錄音,去河邊找鬼周拐。 笑死铡俐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妥粟。 我是一名探鬼主播审丘,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勾给!你這毒婦竟也來(lái)了滩报?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锦秒,失蹤者是張志新(化名)和其女友劉穎露泊,沒(méi)想到半個(gè)月后喉镰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體旅择,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年侣姆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了生真。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沉噩。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柱蟀,靈堂內(nèi)的尸體忽然破棺而出川蒙,到底是詐尸還是另有隱情,我是刑警寧澤长已,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布畜眨,位于F島的核電站,受9級(jí)特大地震影響术瓮,放射性物質(zhì)發(fā)生泄漏康聂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一胞四、第九天 我趴在偏房一處隱蔽的房頂上張望恬汁。 院中可真熱鬧,春花似錦辜伟、人聲如沸氓侧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)约巷。三九已至,卻和暖如春烘豌,著一層夾襖步出監(jiān)牢的瞬間载庭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工廊佩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囚聚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓标锄,卻偏偏與公主長(zhǎng)得像顽铸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子料皇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一谓松、MemCache簡(jiǎn)介 session MemCache是一個(gè)自由、源碼開(kāi)放践剂、高性能鬼譬、分布式的分布式內(nèi)存對(duì)象緩存...
    李偉銘MIng閱讀 3,810評(píng)論 2 13
  • 1、memcache的概念逊脯? Memcache是一個(gè)高性能的分布式的內(nèi)存對(duì)象緩存系統(tǒng)优质,通過(guò)在內(nèi)存里維護(hù)一個(gè)統(tǒng)一的巨...
    桖辶殤閱讀 2,237評(píng)論 2 12
  • 【轉(zhuǎn)】緩存在分布式系統(tǒng)中的應(yīng)用 緩存在分布式系統(tǒng)中的應(yīng)用 摘要 緩存是分布式系統(tǒng)中的重要組件,主要解決高并發(fā),大數(shù)...
    武漢蘇乞兒閱讀 862評(píng)論 0 10
  • Memcached簡(jiǎn)介 Memcached 是一個(gè)高性能的分布式內(nèi)存對(duì)象緩存系統(tǒng)巩螃,用于動(dòng)態(tài)Web應(yīng)用以減輕數(shù)據(jù)庫(kù)負(fù)...
    Bobby0322閱讀 4,904評(píng)論 0 8
  • 枝頭雪意最清新演怎,滿(mǎn)目銀花笑靨真。 若是獨(dú)開(kāi)春一朵避乏,怎留素雅醉紅塵爷耀。
    繁花落盡深眸閱讀 341評(píng)論 6 19