心得:Django框架真的是巨无霸,他的功能太强大,开发企业性质的网站一点都不是问题,完美的功能都给你实现并且有简单的用法,django值得拥有。
一、缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者memcache中之前缓存的内容拿到,并返回。
Django中提供了5种缓存方式:
内存
文件
数据库
Memcache缓存(python-memcached模块)
Memcache缓存(pylibmc模块)
配置内存
# 此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', #保存在内存中适合小数据
'LOCATION': 'unique-snowflake',
'TIMEOUT': 5, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS': {
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
}
}
配置保存在文件中
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #保存在文件中
'LOCATION': r'C:\Users\TianJian\Desktop', #用r来不让路径进行转义
'TIMEOUT': 5, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS': {
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
}
}
配置数据库
# 此缓存将内容保存至数据库
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 数据库表
}
}
# 注:执行创建表命令 python manage.py createcachetable
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缓存(pylibmc模块)
# 此缓存使用pylibmc模块连接memcache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
}
应用到全局
使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# 其他中间件...
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_ALIAS = ""
CACHE_MIDDLEWARE_SECONDS = ""
CACHE_MIDDLEWARE_KEY_PREFIX = ""
应用到视图
from django.views.decorators.cache import cache_page
@cache_page(5)
def cach(request):
obj=models.User.objects.all()
return render(request, "cach.html",{"obj":obj,"time":time.time()})
应用到局部模板
a. 引入TemplateTag
{% load cache %}
b. 使用缓存
{% cache 5000 缓存key %}
缓存内容
{% endcache %}
二、序列化
关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式。
1 serializers
from django.core import serializers
def cach(request):
obj=models.User.objects.all()
data = serializers.serialize("json", obj)
return render(request, "cach.html",{"obj":data,"time":time.time()})
2 json.dumps
转换成对应的字典或者列表的json格式
import json
def cach(request):
obj=models.User.objects.all()
res=json.dumps(list(obj))
return render(request, "cach.html",{"obj":res,"time":time.time()})
由于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)
三、信号
Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
对于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 # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
from django.db.models.signals import pre_init, post_init # django的model执行其构造方法前,自动触发
from django.db.models.signals import pre_save, post_save # django的model对象保存前,自动触发
from django.db.models.signals import pre_delete, post_delete # django的model对象删除前,自动触发
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 # 使用test测试修改配置文件时,自动触发
from django.test.signals import template_rendered # 使用test测试渲染模板时,自动触发
from django.db.backends.signals import connection_created
def callback(sender, **kwargs):
print("xxoo_callback")
print(sender, kwargs)
post_save.connect(callback)
# xxoo指上述导入的内容
四、验证码
更新至登录页面
将文件存在本地并生成验证码,需要用到第三方库pillow处理图片
from PIL import Image, ImageDraw, ImageFont
import random, os
from django.conf import settings
# 随机生成颜色
def random_color():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
def png(request):
img_path = os.path.join(settings.BASE_DIR, 'static/img/')
with open(img_path + '1.png', 'wb') as f:
# 创建image对象并调整大小和颜色
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)) # 小写字母 chr()返回值是当前整数对应的 ASCII 字符。
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)
with open('1.png', 'rb') as f:
image_data = f.read()
将验证码图片保存在内存中
from PIL import Image, ImageDraw, ImageFont
import random
# 随机生成颜色
def random_color():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
def png(request):
# 创建image对象并调整大小和颜色
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)) # 小写字母 chr()返回值是当前整数对应的 ASCII 字符。
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)
from io import BytesIO
f1 = BytesIO()
img_obj.save(f1, format="PNG")
image_data = f1.getvalue()
return HttpResponse(image_data, content_type="image/png")