目錄
一、緩存
1. 配置
1.1 開發調試
1.2 記憶體
1.3 檔案
1.4 資料庫
1.5 Memcache緩存(python-memcached子產品)
1.6 Memcache緩存(pylibmc子產品)
2. 緩存應用
2.1 站點級緩存
2.2 單個視圖緩存
2.3 模闆片段緩存
二、序列化
1、serializers
2、json.dumps
三、信号
1. Django内置信号
一、緩存
由于Django是動态網站,所有每次請求均會去資料進行相應的操作,當程式通路量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存将一個某個views的傳回值儲存至記憶體或者memcache中,5分鐘内再有人來通路時,則不再去執行view中的操作,而是直接從記憶體或者Redis中之前緩存的内容拿到,并傳回。
Django中提供了6種緩存方式:
- 開發調試
- 記憶體
- 檔案
- 資料庫
- Memcache緩存(python-memcached子產品)
- Memcache緩存(pylibmc子產品,隻是與上面換了個子產品而已)
1. 配置
1.1 開發調試
# 此為開始調試用,實際内部不做任何操作
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎
'TIMEOUT': 300, # 緩存逾時時間(預設300,None表示永不過期,0表示立即過期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大緩存個數(預設300)
'CULL_FREQUENCY': 3, # 緩存到達最大個數之後,剔除緩存個數的比例,即:1/CULL_FREQUENCY(預設3)
},
'KEY_PREFIX': '', # 緩存key的字首(預設空)
'VERSION': 1, # 緩存key的版本(預設1)
'KEY_FUNCTION' 函數名 # 生成key的函數(預設函數會生成為:【字首:版本: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,可以不用寫KEY_PREFIX、VERSION、KEY_FUNCTION以及自定義key的函數。
1.2 記憶體
# 此緩存将内容儲存至記憶體的變量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
# 注:其他配置同開發調試版本
1.3 檔案
# 此緩存将内容儲存至檔案
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
# 注:其他配置同開發調試版本
1.4 資料庫
# 此緩存将内容儲存至資料庫
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 資料庫表
}
}
# 注:執行建立表指令 python manage.py createcachetable
使用資料庫緩存之前,你必須用這個指令來建立緩存表:
python manage.py createcachetable
1.5 Memcache緩存(python-memcached子產品)
Memcached有一個非常好的特點就是可以讓幾個服務的緩存共享。 這就意味着你可以在多台機器上運作Memcached服務,這些程式将會把這幾個機器當做 同一個 緩存,進而不需要複制每個緩存的值在每個機器上。為了使用這個特性,把所有的服務位址放在LOCATION裡面,用分号隔開或者當做一個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. 緩存應用
緩存應用分為三種模式:
- 站點級緩存
- 單個視圖緩存
- 模闆片段緩存
2.1 站點級緩存
一旦高速緩存設定,最簡單的方法是使用緩存緩存整個網站。
使用中間件,經過一系列的認證等操作,如果内容在緩存中存在,則使用FetchFromCacheMiddleware擷取内容并傳回給使用者,當傳回給使用者之前,判斷緩存中是否已經存在,如果不存在則UpdateCacheMiddleware會将緩存儲存至緩存,進而實作全站緩存
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# 其他中間件...
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_ALIAS = "" # 用于存儲的緩存的别名
CACHE_MIDDLEWARE_SECONDS = "" # 每個page需要被緩存多少秒。這個優先級大于CACHES中的TIMEOUT參數。
CACHE_MIDDLEWARE_KEY_PREFIX = "" # 如果緩存被使用相同Django安裝的多個網站所共享,那麼把這個值設成目前網站名,或其他能代表這個Django執行個體的唯一字元串,以避免key發生沖突。 如果你不在意的話可以設成空字元串。
注意: 'Update'中間件,必須放在清單的開始位置,而Fectch中間件,必須放在最後。
2.2 單個視圖緩存
#方式一:
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接受一個參數:timeout,秒為機關。在前例中,“my_view()”視圖的結果将被緩存 15 分鐘 (注意為了提高可讀性我們寫了 60 * 15 . 60 * 15 等于 900 –也就是說15分鐘等于60秒乘15.)
2.3 模闆片段緩存
在模版檔案中加入
# a. 引入TemplateTag
{% load cache %}
# b. 使用緩存
{% cache 5000 緩存key %}
緩存内容
{% endcache %}
注意:5000是指緩存5000秒,緩存的key可以是自定義的字元串。
二、序列化
關于Django中的序列化主要應用在将資料庫中檢索的資料傳回給用戶端使用者,特别的Ajax請求一般傳回的為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時無法處理datetime日期,是以可以通過自定義處理器來做擴充,如:
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)
三、信号
Django中提供了“信号排程”,用于在架構執行操作時解耦。通俗來講,就是一些動作發生的時候,信号允許特定的發送者去提醒一些接受者。
1. Django内置信号
Model signals
pre_init # django的modal執行其構造方法前,自動觸發
post_init # django的modal執行其構造方法後,自動觸發
pre_save # django的modal對象儲存前,自動觸發
post_save # django的modal對象儲存後,自動觸發
pre_delete # django的modal對象删除前,自動觸發
post_delete # django的modal對象删除後,自動觸發
m2m_changed # django的modal中使用m2m字段操作第三張表(add,remove,clear)前後,自動觸發
class_prepared # 程式啟動時,檢測已注冊的app中modal類,對于每一個類,自動觸發
Management signals
pre_migrate # 執行migrate指令前,自動觸發
post_migrate # 執行migrate指令後,自動觸發
Request/response signals
request_started # 請求到來前,自動觸發
request_finished # 請求結束後,自動觸發
got_request_exception # 請求異常後,自動觸發
Test signals
setting_changed # 使用test測試修改配置檔案時,自動觸發
template_rendered # 使用test測試渲染模闆時,自動觸發
Database Wrappers
connection_created # 建立資料庫連接配接時,自動觸發
對于Django内置的信号,僅需注冊指定信号,當程式執行相應操作時,自動觸發注冊函數:
需要将觸發信号的代碼放在項目下同項目名稱的目錄下的init.py中,例如django項目名稱為myblog,則需要将下列代碼寫至myblog/myblog/init.py中。
需求:當對某個資料庫做寫入操作時,就觸發某個函數的執行。
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信号測試')
print('sender: ',sender)
print('kwargs: ',kwargs)
# 調用信号的connect方法,将自定義的函數當作參數傳遞進去
post_save.connect(signal) # 當對資料庫做儲存操作時,就會觸發上述signal函數的執行
注意:自定義的函數傳入一個位置參數sender,它是觸發此函數執行的某個子產品;kwargs内容請看下面列印結果;
# 列印結果如下:
# Django信号測試
# 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}