85 缓存, 验证码 序列化
主要内容:http://www.cnblogs.com/maple-shaw/articles/7563029.html
1 缓存: 把数据存在某个地方, 下次再读取的时候不用再去原位置读取
缓存即是将一个某个views的返回值保存至内存或者是memcache中, 在你所设置的时间内, 如果有人再来访问的时候, 则不会再执行view中的操作, 而是直接从内存或者memcache中之前的缓存的内容中拿到.
jango提供的六种缓存方式: 见老师博客:
1: 缓存应用在视图中: 粒度适中
先在settings中设置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', 'LOCATION': 'unique-snowflake', 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 'OPTIONS': { 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, } }
2 接着写url, 视图函数, HTML文件
from django.views.decorators.cache import cache_page @cache_page(15) def user_list(request): print('this is user') all_user = models.User.objects.all() return render(request, 'user.html', {'all_user': all_user})
结论: 在15 秒之内访问该视图, 直接从缓存中取值, 不走数据库, 提高效率
2 缓存在文件中
1 settings里的配置, views里不变
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 'LOCATION': 'C:\cache' , 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 'OPTIONS': { 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, } }
3 全站应用: 力度最大
setings里的配置:
MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', # 其他中间件... 'django.middleware.cache.FetchFromCacheMiddleware', ]
4 局部应用: 粒度最细
用法: 先在模板中{% load cache%}
使用缓存: {% cache 5 '随意的字符串'%}缓存内容{%endcache%}
视图中的用法:
# 局部应用缓存 # 此时应该把中间件中的全站的应用给注销掉 def user_list(request): now = time.time() all_user = models.User.objects.all() return render(request, 'user.html', {'all_user': all_user, 'now': now})
模板中的用法:
<body> {{ now }} <ul> {% cache 5 'asss' %} {{ now }} {% for user in all_user %} <li>{{ user.name }}-{{ user.age }}</li> {% endfor %} {% endcache %} </ul> </body>
2 序列化:关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式。
1 , serializes
from django.core import serializers # def user_list(request): # now = time.time() # all_user = models.User.objects.all() # print(all_user) # # <QuerySet [<User: User object>, <User: User object>, <User: User object>]> # data = serializers.serialize('json', all_user) # print('this si 序列化的结果', data) # # [{"model": "app01.user", "pk": 1, "fields": {"name": "\u8bd7\u8bd7", "age": 28}},]
2 , json.dumps, 由于queryset不支持dumps, 所以转换成list
all_user = models.User.objects.all().values('name') # <QuerySet [{'name': '诗诗'}, {'name': '菲菲'}, {'name': '圆圆'}]> all_user1 = models.User.objects.all().values_list('name') ret = list(all_user1) # 把ret转换成列表 # [('诗诗',), ('菲菲',), ('圆圆',)] result = json.dumps(ret) print(result) # <QuerySet [('诗诗',), ('菲菲',), ('圆圆',)]>
3 , 由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:
import json from datetime import datetime, date data = [ {"pk": 1, "name": "\u83b9\u83b9", "age": 18, 'birth': datetime.now()}, {"pk": 2, "name": "\u5c0f\u5fae", "age": 16, 'birth': datetime.now()}, {"pk": 3, "name": "\u5c0f\u9a6c\u54e5", "age": 8, 'birth': datetime.now()}, {"pk": 4, "name": "qqq", "age": 5, 'birth': datetime.now()}, {"pk": 5, "name": "www", "age": 5, 'birth': datetime.now()} ] # 由于日期类型不支持json序列化, 所以自定义类来扩展: class JsonCustomEncoder(json.JSONEncoder): def default(self, field): if isinstance(field, datetime): return field.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(field, date): return field.strftime('%Y-%m-%d') else: return json.JSONEncoder.default(self, field) print(json.dumps(data, cls=JsonCustomEncoder))
3 信号:Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
1 : jango的内置信号,见老师博客
2 : 用法:对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:注册信号,写入与project同名的文件夹下的_init_.py文件中,也是换数据库引擎的地方。
from django.db.models.signals import pre_save, post_save # 方法一 def callback(sender, **kwargs): print("xxoo_callback") print(sender, kwargs) post_save.connect(callback)
3 在创建对象的时候, 自动触发注册函数
def get_value(request): # users = models.User.objects.all().values('pk', 'name', 'age') users = models.User.objects.create(name='ale', age=12) # ret = serializers.serialize('json', users) # ret = serializers.serialize('json', users) return HttpResponse('ok') # 触发显示的内容: # xxoo_callback # <class 'app01.models.User'> {'signal': <django.db.models.signals.ModelSignal object at 0x0000026D2F38F898>, 'instance': <User: User object>, 'created': True, 'update_fields': None, 'raw': False, 'using': 'default'}
自定义信号见老师博客
4 验证码:
1 生成随机验证码:
import random from PIL import Image, ImageDraw, ImageFont def random_color(): return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) def code(): with open('1.png', 'wb') as f: img_obj = Image.new('RGB', (250, 35), random_color()) # 在该图片对象上生成一个画笔对象 draw_obj = ImageDraw.Draw(img_obj) font_obj = ImageFont.truetype('static/font/kumo.ttf', 28) temp = [] for i in range(5): l = chr(random.randint(97, 122)) # 小写字母 b = chr(random.randint(65, 90)) # 大写字母 n = str(random.randint(0, 9)) t = random.choice([l, b, n]) temp.append(t) # 加线 draw_obj.text((i * 40 + 35, 0), t, fill=random_color(), font=font_obj) img_obj.save(f) code()