目錄
一祠饺、緩存
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}