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

緩存、序列化、信號

change 內容 emc class 文件 ria 序列化 rem 頂部

https://www.cnblogs.com/maple-shaw/articles/7563029.html

一、緩存

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

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

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

1、配置

a、開發調試

技術分享圖片
 1  # 此為開始調試用,實際內部不做任何操作
 2     # 配置:
 3         CACHES = {
 4             default: {
 5                 BACKEND: django.core.cache.backends.dummy.DummyCache,     # 引擎
 6                 TIMEOUT: 300,                                               # 緩存超時時間(默認300,None表示永不過期,0表示立即過期)
7 OPTIONS:{ 8 MAX_ENTRIES: 300, # 最大緩存個數(默認300) 9 CULL_FREQUENCY: 3, # 緩存到達最大個數之後,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) 10 }, 11 KEY_PREFIX
: ‘‘, # 緩存key的前綴(默認空) 12 VERSION: 1, # 緩存key的版本(默認1) 13 KEY_FUNCTION 函數名 # 生成key的函數(默認函數會生成為:【前綴:版本:key】) 14 } 15 } 16 17 18 # 自定義key 19 def default_key_func(key, key_prefix, version): 20 """ 21 Default function to generate keys. 22 23 Constructs the key used by all other methods. By default it prepends 24 the `key_prefix‘. KEY_FUNCTION can be used to specify an alternate 25 function with custom key making behavior. 26 """ 27 return %s:%s:%s % (key_prefix, version, key) 28 29 def get_key_func(key_func): 30 """ 31 Function to decide which key function to use. 32 33 Defaults to ``default_key_func``. 34 """ 35 if key_func is not None: 36 if callable(key_func): 37 return key_func 38 else: 39 return import_string(key_func) 40 return default_key_func
View Code

b、內存

技術分享圖片
 1   # 此緩存將內容保存至內存的變量中
 2     # 配置:
 3         CACHES = {
 4             default: {
 5                 BACKEND: django.core.cache.backends.locmem.LocMemCache,
 6                 LOCATION: unique-snowflake,
 7             }
 8         }
 9 
10     # 註:其他配置同開發調試版本
View Code

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,
            ]
        }
    }

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,
            ]
        }
    }

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、serializer

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

2、json.dumps

1 import json
2  
3 #ret = models.BookType.objects.all().values(‘caption‘)
4 ret = models.BookType.objects.all().values_list(caption)
5  
6 ret=list(ret)
7  
8 result = json.dumps(ret)

由於json.dumps時無法處理datetime日期,所以可以通過自定義處理器來做擴展,如:

 1 import json 
 2 from datetime import date 
 3 from datetime import datetime 
 4    
 5 class JsonCustomEncoder(json.JSONEncoder): 
 6     
 7     def default(self, field): 
 8      
 9         if isinstance(field, datetime): 
10             return o.strftime(%Y-%m-%d %H:%M:%S) 
11         elif isinstance(field, date): 
12             return o.strftime(%Y-%m-%d) 
13         else: 
14             return json.JSONEncoder.default(self, field) 
15    
16    
17 # ds = json.dumps(d, cls=JsonCustomEncoder) 

回到頂部

三、信號

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

1、Django內置信號

 1 Model signals
 2     pre_init                    # django的model執行其構造方法前,自動觸發
 3     post_init                   # django的model執行其構造方法後,自動觸發
 4     pre_save                    # django的model對象保存前,自動觸發
 5     post_save                   # django的model對象保存後,自動觸發
 6     pre_delete                  # django的model對象刪除前,自動觸發
 7     post_delete                 # django的model對象刪除後,自動觸發
 8     m2m_changed                 # django的model中使用m2m字段操作第三張表(add,remove,clear)前後,自動觸發
 9     class_prepared              # 程序啟動時,檢測已註冊的app中modal類,對於每一個類,自動觸發
10 Management signals
11     pre_migrate                 # 執行migrate命令前,自動觸發
12     post_migrate                # 執行migrate命令後,自動觸發
13 Request/response signals
14     request_started             # 請求到來前,自動觸發
15     request_finished            # 請求結束後,自動觸發
16     got_request_exception       # 請求異常後,自動觸發
17 Test signals
18     setting_changed             # 使用test測試修改配置文件時,自動觸發
19     template_rendered           # 使用test測試渲染模板時,自動觸發
20 Database Wrappers
21     connection_created          # 創建數據庫連接時,自動觸發

對於Django內置的信號,僅需註冊指定信號,當程序執行相應操作時,自動觸發註冊函數:

註冊信號,寫入與project同名的文件夾下的_init_.py文件中,也是換數據庫引擎的地方。

 1    from django.core.signals import request_finished
 2     from django.core.signals import request_started
 3     from django.core.signals import got_request_exception
 4 
 5     from django.db.models.signals import class_prepared
 6     from django.db.models.signals import pre_init, post_init
 7     from django.db.models.signals import pre_save, post_save
 8     from django.db.models.signals import pre_delete, post_delete
 9     from django.db.models.signals import m2m_changed
10     from django.db.models.signals import pre_migrate, post_migrate
11 
12     from django.test.signals import setting_changed
13     from django.test.signals import template_rendered
14 
15     from django.db.backends.signals import connection_created
16 
17 
18     def callback(sender, **kwargs):
19         print("xxoo_callback")
20         print(sender,kwargs)
21 
22     xxoo.connect(callback)
 1 def my_callback(sender, **kwargs):
 2     print("Request finished!")
 3 
 4 # 方法一:
 5 from django.core.signals import request_finished
 6 
 7 request_finished.connect(my_callback)
 8 
 9 # 方法二:
10 from django.core.signals import request_finished
11 from django.dispatch import receiver
12 
13 @receiver(request_finished)
14 def my_callback(sender, **kwargs):
15     print("Request finished!")
1 from django.db.models.signals import pre_save
2 from django.dispatch import receiver
3 from myapp.models import MyModel
4 
5 
6 @receiver(pre_save, sender=MyModel)
7 def my_handler(sender, **kwargs):
8     ...

2、自定義信號

a. 定義信號

在某py文件中定義信號。

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

b. 註冊信號

在_init_.py 中註冊信號

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

c. 觸發信號

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

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

更多:猛擊這裏

緩存、序列化、信號