因爲Django是動態網站,全部每次請求均會去數據進行相應的操做,當程序訪問量大時,耗時必然會更加html
明顯,最簡單解決方式是使用:緩存,緩存將一個某個views的返回值保存至內存或者memcache中,5分python
鍾內再有人來訪問時,則再也不去執行view中的操做,而是直接從內存或者Redis中以前緩存的內容拿到,並redis
返回。數據庫
Django中提供了6種緩存方式:django
開發調試json
內存緩存
文件app
數據庫dom
Memcache緩存(python-memcached模塊)memcached
Memcache緩存(pylibmc模塊)
配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
'TIMEOUT': 300, # 緩存超時時間(默認300,None表示永不過時,0表示當即過時)
'OPTIONS': {
'MAX_ENTRIES': 300, # 最大緩存個數(默認300)
'CULL_FREQUENCY': 3, # 緩存到達最大個數以後,剔除緩存個數的比例,即1/CULL_FREQUENCY(默認3)
},
}
}redis
django-redis
應用
應用到視圖上: 粒度適中
from django.views.decorators.cache import cache_page
@cache_page(15)
def user_list(request):
print('user_list')
users = models.User.objects.all()
return render(request, 'user_list.html', {'users': users})全站應用: 粒度最大
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# 其餘中間件...
'django.middleware.cache.FetchFromCacheMiddleware',
]局部視圖:粒度最細
a. 引入TemplateTag
{% load cache %}
b. 使用緩存
{% cache 5000 緩存key %}
緩存內容
{% endcache %}
json pickle
- 自定義序列化
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))
信號 問題: 數據庫增長一條數據的時候,記錄一條日誌。
內置信號
Model signals
pre_init # django的model執行其構造方法前,自動觸發
post_init # django的model執行其構造方法後,自動觸發
pre_save # django的model對象保存前,自動觸發
post_save # django的model對象保存後,自動觸發
pre_delete # django的model對象刪除前,自動觸發
post_delete # django的model對象刪除後,自動觸發
m2m_changed # django的model中使用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 # 建立數據庫鏈接時,自動觸發
註冊信號
# 方法一
def callback(sender, **kwargs):
print("xxoo_callback")
print(sender, kwargs)post_save.connect(callback)
# 方法二
@receiver(post_save)
def my_callback(sender, **kwargs):
print("xxoo_callback")
print(sender, kwargs)
- ORM性能相關
1. [{} ]
all_users = models.User.objects.all().values('name','age','role__name')
2. [ 對象 ]
all_users = models.User.objects.all()
用的時候注意,只拿本身表中的字段,別跨表
3. select_related (外鍵、一對一)
all_users = models.User.objects.all().select_related('role')
4. prefetch_related (role)
all_users = models.User.objects.all().prefetch_related('role')
5. only
all_users = models.User.objects.all().only('name')
用的時候注意,只拿本身指定的字段
6. defer
all_users = models.User.objects.all().defer('name')
- 驗證碼
from PIL import Image, ImageDraw, ImageFont
import randomdef random_color():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)def v_code(request):
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)
from io import BytesIO
f1 = BytesIO()
img_obj.save(f1, format="PNG")
img_data = f1.getvalue()
return HttpResponse(img_data, content_type='image/png')