Django组件、缓存、信号、序列化 ????
http://www.cnblogs.com/yuanchenqi/articles/8034442.html 日天博客
Django的缓存机制
Django提供了6种缓存方式
- 开发调试缓存
- 内存缓存
- 文件缓存
- 数据库缓存
- Memcache缓存(使用python-memcached模块)
- Memcache缓存(使用pylibmc模块)
各种缓存配置
1、文件缓存(把缓存数据存储在文件中)
settings.py文件配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎 'LOCATION': '/var/tmp/django_cache', #指定缓存的路径 'TIMEOUT':300, #缓存超时时间(默认为300秒,None表示永不过期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)》》》缓存总数里面内容,清空三分之一,是随机清空 } } }
2、内存缓存如下:
视图级别的缓存 》》》加一个装饰器,只缓存加装饰器的这个函数,表示:只有这个函数放到了缓存,其他的并没有放入。
数据库:
class Book(models.Model): name=models.CharField(max_length=32) price=models.DecimalField(max_digits=6,decimal_places=1)
视图:
from django.views.decorators.cache import cache_page #需要先引入这个 import time from .models import * #下面的15也可写成这种形式(60*15);也可弄个时间戳,然后弄个创建时间,每隔几秒从数据库中取数据,也就是可弄一个实时刷新 @cache_page(15) #超时时间为15秒 #15秒的有效期,设置了这个之后,在index里面缓存了15秒的数据,这样就不走数据库了,等15秒之后,再走数据库 def index(request): t=time.time() #获取当前时间 bookList=Book.objects.all() return render(request,"index.html",locals()) #重点,这个是缓存的render括弧内的数据,并不是缓存下面的函数,而是返回的这个页面
模板(index.html):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>当前时间:-----{{ t }}</h3> <ul> {% for book in bookList %} <li>{{ book.name }}--------->{{ book.price }}$</li> {% endfor %} </ul> </body> </html>
3、全站使用缓存》》》
中间件级别缓存 》》》》》这是整个页面的缓存,也就是全局缓存
既然是全站缓存,当然要使用Django中的中间件.
缓存整个站点,是最简单的缓存方法:》》》》用户的请求通过中间件,经过一系列的认证等操作,如果请求的内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户;
当返回给用户之前,判断缓存中是否已经存在,如果不存在,则UpdateCacheMiddleware会将缓存保存至Django的缓存之中,以实现全站缓存。
在 MIDDLEWARE_CLASSES 中加入 “update” 和 “fetch” 中间件
“update” 必须配置在第一个,把这个加在我们总settings中间件的第一行,下面的放到最后一行。 “fetch” 必须配置在最后一个
MIDDLEWARE_CLASSES = ( 'django.middleware.cache.UpdateCacheMiddleware', #响应HttpResponse中设置几个headers 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', #用来缓存通过GET和HEAD方法获取的状态码为200的响应 ) CACHE_MIDDLEWARE_SECONDS=10 #限制中间件缓存时间的,这里是10秒
就这样就完成了中间件的全局缓存操作。
4、局部缓存》》》》只需要在html模板里面进行操作即可,不需要设置中间件等之类的。
只对一个页面的局部进行缓存》》》缓存机制,这个数据在django自己的一块内置内存上;
{% load cache %} #注意这里 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3 style="color: green">不缓存:-----{{ t }}</h3> {% cache 2 'name' %} #2表示秒; “name” 是起个名字,这个名字可以随便起,但是一定要有,因为这里需要两个参数。 <h3>缓存:-----:{{ t }}</h3> #需要缓存的放在这个里面 {% endcache %} </body> </html>
Django的信号
Django中提供了"信号调度",用于在框架执行操作时解耦.; 一些动作发生的时候,系统会根据信号定义的函数执行相应的操作
信号的作用: 举例说明: 你在数据库前边写了个信号,用于监控谁操作了数据库,只要数据库一变动,你就能收到变动信息 。
信号绑定,一般把代码放在init里面,因django启动的时候,就会执行init
Django内置信号
Model signals #跟model相关的 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内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:
方式一、
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("pre_save_callback") print(sender,kwargs) pre_save.connect(callback) # 该脚本代码需要写到app或者项目的初始化文件中,当项目启动时执行注册代码
方式2:》》》利用装饰器》》也可以使用装饰器来触发信号,把上面__init__.py
中的代码修改:
(http://www.cnblogs.com/haiyan123/p/8259647.html,参考网址或者日天博客)
from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished) def callback(sender, **kwargs): print("Request finished!")
自定义信号 (信号不够用的时候,自定义设置信号)
1.定义信号
新建一个项目,配置好路由,在项目根目录下创建一个singal_test.py
的文件,内容为
import django.dispatch action=django.dispatch.Signal(providing_args=["aaaa","bbbb"])
2.注册信号
项目应用下面的__init__.py
文件内容:
from singal_test import action def pre_save_func(sender,**kwargs): print("pre_save_func") print("pre_save_msg:",sender,kwargs) action.connect(pre_save_func)
3.触发信号
views视图函数内容:
from singal_test import action action.send(sender="python",aaa="111",bbb="222")
用浏览器打开index.html
网页,后台打印信息如下:
pre_save_func pre_save_msg: python {'signal': <django.dispatch.dispatcher.Signal object at 0x000000000391D710>, 'aaa': '111', 'bbb': '222'}
由于内置信号的触发者已经集成到Django中,所以会自动调用,而对于自定义信号需要在任意位置触发。
老师讲课信号举例:
![](https://images2018.cnblogs.com/blog/1145506/201803/1145506-20180331181404311-891550097.png)
![](https://images2018.cnblogs.com/blog/1145506/201803/1145506-20180331181422153-658343302.png)
ps:这就能监听,比如某表中生成了某一个的实例对象。