补充ORM块:
1.select_related() # 解决:当有外健,规避多决查询,使用了join. 多次查询变成一次查询
例:UserInfo.objects.all().select_related('ut') # FK字段名称
2.prefetch_related() # 解决: 当使用join表太多,性能下降,将每次join查询分解单表查询,拿到数据再组合。
例:UserInfo.objects.filter(id=1).prefetch_realated('ut') # FK字段名称
3.通常UserInfo.objects.all()取数据性能不高,和values or vlaues_list基本差不多
(1) UserInfo.objects.all().only('id,'name') # 只取这两列,但是当你取数据的时候其实其它字段也是可以取的,那样性能又和all()一样了。
(2) UserInfo.objects.all().defer('id) # 除了这列都取
一、缓存
基于内存缓存配置:
1.settings.py
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'unique-snowflake', 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 'OPTIONS': { 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 'CULL_FREQUENCY': 10, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, # 'KEY_PREFIX': 'prev', # 缓存key的前缀(默认空) # 'VERSION': 1, # 缓存key的版本(默认1) # 'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】) } }
2.全站使用缓存
MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', # 其他中间件... 'django.middleware.cache.FetchFromCacheMiddleware', ]
3.单独视图使用
from django.shortcuts import render import time from django.views.decorators.cache import cache_page @cache_page(10) # 10秒 def index(request): ctime = time.time() return render(request,'index.html',{'ctime': ctime})
templates/index.html
<h3>{{ ctime }}</h3>
4.页面局部使用
templates/index.html
1 {% load cache %} 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <title></title> 7 </head> 8 <body> 9 {% cache 5000 keyname %} 10 <h1>{{ ctime }}</h1> 11 {% endcache %} 12 13 <h3>{{ ctime }}</h3> 14 </body>
二、信号
1.内置信号
1 Model signals 2 pre_init # django的modal执行其构造方法前,自动触发 3 post_init # django的modal执行其构造方法后,自动触发 4 pre_save # django的modal对象保存前,自动触发 5 post_save # django的modal对象保存后,自动触发 6 pre_delete # django的modal对象删除前,自动触发 7 post_delete # django的modal对象删除后,自动触发 8 m2m_changed # django的modal中使用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 # 创建数据库连接时,自动触发
2.配置
mysite/mysite/__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 # sender 请求的所有信息 19 def callback(sender, **kwargs): 20 print("xxoo_callback") 21 print(sender,kwargs) 22 23 request_finished.connect(callback)
3.自定义信号
a.定义信号
import django.dispatch pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
b.注册信号
def callback(sender, **kwargs): print("callback") print(sender,kwargs) pizza_done.connect(callback
c.触发信号
from 路径 import pizza_done pizza_done.send(sender='seven',toppings=123, size=456)
三、模态+Ajax+Form验证
1.templates/index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> 7 8 <style> 9 .modal-body span { 10 color:red; 11 } 12 13 .modal-body p { 14 margin-left: 100px; 15 } 16 </style> 17 </head> 18 <body> 19 20 21 <!--按钮 --> 22 <button id="tologin" type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> 23 登录 24 </button> 25 26 <!-- Modal --> 27 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> 28 <div class="modal-dialog" role="document"> 29 <div class="modal-content"> 30 <div class="modal-header"> 31 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> 32 <h4 class="modal-title" id="myModalLabel">登录</h4> 33 </div> 34 <div class="modal-body"> 35 <p><input type="text" id="username" name="username" placeholder="用户名" /></p> 36 <p><input type="password" id="password" name="password" placeholder="密码"/></p> 37 </div> 38 <div class="modal-footer"> 39 <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> 40 <button id="sbm" type="button" class="btn btn-primary">提交</button> 41 </div> 42 </div> 43 </div> 44 </div> 45 46 <script src="/static/jquery-1.12.4.js"></script> 47 <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script> 48 49 <script> 50 $(function () { 51 $('#sbm').click(function () { 52 $.ajax({ 53 url: '/login/', 54 type: 'POST', 55 data: {'username': $('#username').val(),'password': $('#password').val()}, 56 dataType: 'JSON', 57 success:function (arg) { 58 if(arg.status){ 59 }else{ 60 $.each(arg.error,function (k,v) { 61 // k = username,v = ["This field is required",] 62 var tag = document.createElement('span'); 63 tag.innerHTML = v[0]; 64 $('#' + k).next().remove(); 65 $('#' + k).after(tag); 66 }) 67 } 68 } 69 }) 70 71 }) 72 }) 73 </script> 74 </body> 75 </html>
2.urls.py
url(r'^index/', views.index), url(r'^login/', views.login),
3.views.py
1 from django.shortcuts import render, HttpResponse 2 import time 3 from app01.models import * 4 import json 5 from django.forms import Form 6 from django.forms import fields 7 8 # Create your views here. 9 # 规范返回数据 10 class BaseReponse: 11 def __init__(self): 12 self.status = False 13 self.data = None 14 self.error = None 15 16 # 表单验证 17 class LoginForm(Form): 18 username = fields.CharField(error_messages={'required': "用户名不能为空"}) 19 password = fields.CharField(error_messages={'required': "密码不能为空"}) 20 21 # 页面 22 def index(request): 23 return render(request, 'index.html', locals()) 24 25 # 验证视图 26 def login(request): 27 response = BaseReponse() 28 try: 29 obj = LoginForm(request.POST) 30 if obj.is_valid(): 31 v = UserInfo.objects.filter(**obj.cleaned_data).first() 32 if v: 33 response.status = True
request.session['username']= v.username 34 else: 35 response.status = False 36 response.error = "用户名或密码错误" 37 else: 38 response.status = False 39 response.error = obj.errors 40 except Exception as e: 41 response.status = False 42 43 return HttpResponse(json.dumps(response.__dict__, ensure_ascii=False))
4."登录"或者"用户名"
{% if request.session.username %} {{ request.session.username }} {% else %} 登录 {% endif %}
四、三种上传方式
方式一:Form表单上传文件
1.views.py
1 def upload(request): 2 if request.method == 'GET': 3 return render(request, 'upload.html') 4 else: 5 obj = request.FILES.get('fffff') 6 f = open(obj.name, 'wb') 7 for chunk in obj.chunks(): 8 f.write(chunk) 9 f.close() 10 return render(request, 'upload.html', locals())
2.templates/upload.html
1 <form action="/upload/" method="post" enctype="multipart/form-data"> 2 {% csrf_token %} 3 <input type="file" name="fffff" > 4 <input type="submit" value="提交"> 5 </form>
方式二:Ajax上传文件(只支持新浏览器HMTL5)
1.views.py
1 def ajaxupload(request): 2 import os 3 response = BaseReponse() 4 try: 5 obj = request.FILES.get('fffff') 6 file_path = os.path.join('static', obj.name) 7 f = open(file_path, 'wb') 8 for chunk in obj.chunks(): 9 f.write(chunk) 10 f.close() 11 response.status = True 12 response.data = file_path 13 except Exception as e: 14 response.status = False 15 return HttpResponse(json.dumps(response.__dict__, ensure_ascii=False))
2.templates/upload.html
1 <h1>方式二:Ajax上传文件(不兼容老浏览器)</h1> 2 <input type="file" id="ggggg"> 3 <a id="btn1">提交</a> 4 5 <script src="/static/jquery-1.12.4.js"></script> 6 <script src="/static/jquery.cookie.js"></script> # 从COOKIE获取CSRF的信息。 7 <script> 8 $(function(){ 9 $("#btn1").click(function(){ 10 var fm = new FormData(); 11 fm.append('fffff', document.getElementById('ggggg').files[0]); 12 $.ajax({ 13 url: "/ajaxupload/", 14 type: 'POST', 15 data: fm, 16 headers:{ "X-CSRFtoken":$.cookie("csrftoken")}, # 解决CSRF 17 processData: false, // tell jQuery not to process the data 18 contentType: false, // tell jQuery not to set contentType 19 success:function(arg){ 20 console.log(arg); 21 } 22 }) 23 }) 24 }) 25 </script>
方式三:iframe上传文件(伪ajax)
1.views.py
1 def ifreamupload(request): 2 import os 3 response = BaseReponse() 4 if request.method == 'GET': 5 return render(request, 'ifreamupload.html') 6 else: 7 try: 8 obj = request.FILES.get('fffff') 9 file_path = os.path.join('static', obj.name) 10 f = open(file_path, 'wb') 11 for chunk in obj.chunks(): 12 f.write(chunk) 13 f.close() 14 response.status = True 15 response.data = file_path 16 except Exception as e: 17 response.status = False 18 return HttpResponse(json.dumps(response.__dict__, ensure_ascii=False))
2.templates/ifreamupload.html
1 <h1>iframe upload</h1> 2 <form action="/ifreamupload/" method="post" id="ff1" enctype="multipart/form-data" target="ifr"> 3 {% csrf_token %} 4 <input type="file" name="fffff" onchange="changeImg();"> 5 </form> 6 <iframe id="ifr" name="ifr" onload="successBack();" style="display: none"></iframe> 7 <div id="prevImg"></div> 8 9 10 <script src="/static/jquery-1.12.4.js"></script> 11 <script> 12 // 获取回来的数据信息. 13 function successBack(){ 14 var v = $('#ifr').contents().find('body').html(); 15 var obj = JSON.parse(v); 16 17 var tag = document.createElement('img'); 18 tag.src = '/' + obj.data; 19 console.log(tag); 20 $("#prevImg").append(tag); 21 } 22 23 // 自动提交,不需要提交按钮. 24 function changeImg(){ 25 document.getElementById('ff1').submit(); 26 } 27 </script>