1. 程式人生 > >Django 緩存、序列化、信號

Django 緩存、序列化、信號

分享圖片 cif cep 解決 解耦 which 地方 cli cells

緩存、序列化、信號

一、緩存

由於Django是動態網站,所有每次請求均會去數據進行相應的操作,當程序訪問量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存將一個某個views的返回值保存至內存或者memcache中,5分鐘內再有人來訪問時,則不再去執行view中的操作,而是直接從內存或者memcache中之前緩存的內容拿到,並返回。

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

  • 開發調試
  • 內存
  • 文件
  • 數據庫
  • Memcache緩存(python-memcached模塊)
  • Memcache緩存(pylibmc模塊)

1、配置

a、開發調試

技術分享圖片
 # 此為開始調試用,實際內部不做任何操作
    # 配置:
        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
開發調試

b、內存

技術分享圖片
# 此緩存將內容保存至內存的變量中
    # 配置:
        CACHES = {
            default: {
                BACKEND: django.core.cache.backends.locmem.LocMemCache,
                LOCATION: unique-snowflake,
            }
        }

    # 註:其他配置同開發調試版本
內存

c、文件

技術分享圖片
    # 此緩存將內容保存至文件
    # 配置:

        CACHES = {
            default: {
                BACKEND: django.core.cache.backends.filebased.FileBasedCache,
                LOCATION: /var/tmp/django_cache,
            }
        }
    # 註:其他配置同開發調試版本
文件

d、數據庫

技術分享圖片
   # 此緩存將內容保存至數據庫

    # 配置:
        CACHES = {
            default: {
                BACKEND: django.core.cache.backends.db.DatabaseCache,
                LOCATION: my_cache_table, # 數據庫表
            }
        }

    # 註:執行創建表命令 python manage.py createcachetable
數據庫

e、Memcache緩存(python-memcached模塊)

技術分享圖片
# 此緩存使用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,
            ]
        }
    }
Memcache緩存

f、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,
            ]
        }
    }
Memcache緩存

2、應用(粒度控制使用)

a. 全站使用

技術分享圖片
 使用中間件,經過一系列的認證等操作,如果內容在緩存中存在,則使用FetchFromCacheMiddleware獲取內容並返回給用戶,當返回給用戶之前,判斷緩存中是否已經存在,如果不存在則UpdateCacheMiddleware會將緩存保存至緩存,從而實現全站緩存

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

    CACHE_MIDDLEWARE_ALIAS = ""
    CACHE_MIDDLEWARE_SECONDS = ""
    CACHE_MIDDLEWARE_KEY_PREFIX = ""
全站使用(所有的)

b. 單獨視圖緩存

技術分享圖片
    方式一:
        from django.views.decorators.cache import cache_page

        @cache_page(60 * 15)
        def my_view(request):
            ...

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

        urlpatterns = [
            url(r^foo/([0-9]{1,2})/$, cache_page(60 * 15)(my_view)),
        ]
單獨視圖使用緩存

c、局部模板使用

技術分享圖片
   a. 引入TemplateTag

        {% load cache %}

    b. 使用緩存

        {% cache 5000 緩存key %}
            緩存內容
        {% endcache %}
局部模板使用

二、序列化

關於Django中的序列化主要應用在將數據庫中檢索的數據返回給客戶端用戶,特別的Ajax請求一般返回的為Json格式。

1、serializers

1 2 3 4 5 from django.core import serializers ret = models.BookType.objects.all() data = serializers.serialize("json", ret)

2、json.dumps

1 2 3 4 5 6 7 8 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) 
json無法處理數據類型解決方法

三、信號

Django中提供了“信號調度”,用於在框架執行操作時解耦。通俗來講,就是一些動作發生的時候,信號允許特定的發送者去提醒一些接受者。

1、Django內置信號

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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內置的信號,僅需註冊指定信號,當程序執行相應操作時,自動觸發註冊函數:

註冊信號,寫入與project同名的文件夾下的_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 callback(sender, **kwargs):
        print("xxoo_callback")
        print(sender,kwargs)

    xxoo.connect(callback)
    # xxoo指上述導入的內容
所有信號導入 技術分享圖片
def my_callback(sender, **kwargs):
    print("Request finished!")

# 方法一:
from django.core.signals import request_finished

request_finished.connect(my_callback)

# 方法二:
from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")
示例 技術分享圖片
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel


@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
    ...
指定發送者

2、自定義信號

a. 定義信號

在某py文件中定義信號。

1 2 import django.dispatch pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

b. 註冊信號

在_init_.py 中註冊信號

1 2 3 4 5 def callback(sender, **kwargs): print("callback") print(sender,kwargs) pizza_done.connect(callback)

c. 觸發信號

1 2 3 from 路徑 import pizza_done pizza_done.send(sender=‘seven‘,toppings=123, size=456)

由於內置信號的觸發者已經集成到Django中,所以其會自動調用,而對於自定義信號則需要開發者在任意位置觸發。

Django 緩存、序列化、信號