day72 2018-06-27
1. 内容回顾
1. 中间件 1. 中间件概念 2. 中间件应用的场景 对请求和相应做全局修改/处理 3. Django中间件的用法 1. 按照格式要求自己写一个类 1. from django.utils.deprecation import MiddlewareMixin 我们写的中间件的类要继承 MiddlewareMixin 2. 定义相应的方法(5种可以选择) 1. process_request(self, request) 1. 何时执行 2. 执行的顺序 --> 注册的正序 3. 返回值 1. 返回None --> 继续往后执行 2. 返回Response对象 --> 跳出直接返回响应(按照处理响应的操作继续往后执行) 2. process_view(self, request, view_func, args, kwargs) 1. 何时执行 2. 执行的顺序 --> 注册的正序 3. 返回值 1. 返回None --> 继续往后执行 2. 返回Response对象 --> 跳出直接返回响应(按照处理响应的操作继续往后执行) 3. process_exception(self, request, exception) 4. process_template_response(self, request, response) 5. process_response(self, request, response) 1. 何时执行 2. 执行的顺序 --> 注册的倒序 3. 返回值 1. 必须返回一个response
2. 去settings.py里注册/配置 我写的类
https://pymotw.com/3/py-modindex.html
importlib模块的基本使用
2. Django请求的生命周期
边画边说
补充
利用Django中间件实现网站访问频率限制。
具体要求是:每个ip一分钟最多访问5次,超过5次就加入黑名单。
提示:获取访问者ip的方法:request.META.get("REMOTE_ADDR")
history = {
ip: {"last": 09:20:10, "times": 1},
}
2. 今日内容
https://www.cnblogs.com/liwenzhou/p/8718861.html
1. AJAX预备知识点
1. Python中
dict <==> JSON格式字符串
json.loads()
json.dumps()
python中序列化
2. JavaScript中:
SON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
JSON 是轻量级的文本数据交换格式
合格的json对象:
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["张三", "李四"] } [ { "name": "张三"}, {"name": "李四"} ]
不合格的json对象:
{ name: "张三", 'age': 32 } // 属性名必须使用双引号 [32, 64, 128, 0xFFF] // 不能使用十六进制值 { "name": "张三", "age": undefined } // 不能使用undefined { "name": "张三", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() {return this.name;} // 不能使用函数和日期对象 }
obj <==> JSON格式字符串
javaScript中序列化
stringify与parse方法
JavaScript中关于JSON对象和字符串转换的两个方法:
JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象
JSON.parse('{"name":"Q1mi"}');
JSON.parse('{name:"Q1mi"}') ;
// 错误
JSON.parse('[18,undefined]') ; // 错误
JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
JSON.stringify({"name":"Q1mi"})
JSON.parse()
JSON.stringify()
和XML的比较
SON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁琐笨重的 XML 格式。 JSON 格式有两个显著的优点:书写简单,一目了然;符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。所以,JSON迅速被接受,已经成为各大网站交换数据的标准格式,并被写入ECMAScript 5,成为标准的一部分。 XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。 用XML表示中国部分省市数据如下: <?xml version="1.0" encoding="utf-8"?> <country> <name>中国</name> <province> <name>黑龙江</name> <cities> <city>哈尔滨</city> <city>大庆</city> </cities> </province> <province> <name>广东</name> <cities> <city>广州</city> <city>深圳</city> <city>珠海</city> </cities> </province> <province> <name>台湾</name> <cities> <city>台北</city> <city>高雄</city> </cities> </province> <province> <name>新疆</name> <cities> <city>乌鲁木齐</city> </cities> </province> </country> 用JSON表示如下: { "name": "中国", "province": [{ "name": "黑龙江", "cities": { "city": ["哈尔滨", "大庆"] } }, { "name": "广东", "cities": { "city": ["广州", "深圳", "珠海"] } }, { "name": "台湾", "cities": { "city": ["台北", "高雄"] } }, { "name": "新疆", "cities": { "city": ["乌鲁木齐"] } }] }
由上面的两端代码可以看出,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用得带宽。
示例
页面输入两个整数,通过AJAX传输到后端计算出结果并返回。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>AJAX局部刷新实例</title> </head> <body> <input type="text" id="i1">+ <input type="text" id="i2">= <input type="text" id="i3"> <input type="button" value="AJAX提交" id="b1"> <script src="/static/jquery-3.2.1.min.js"></script> <script> $("#b1").on("click", function () { $.ajax({ url:"/ajax_add/", type:"GET", data:{"i1":$("#i1").val(),"i2":$("#i2").val()}, success:function (data) { $("#i3").val(data); } }) }) </script> </body> </html>
def ajax_demo1(request): return render(request, "ajax_demo1.html") def ajax_add(request): i1 = int(request.GET.get("i1")) i2 = int(request.GET.get("i2")) ret = i1 + i2 return JsonResponse(ret, safe=False)
urlpatterns = [ ... url(r'^ajax_add/', views.ajax_add), url(r'^ajax_demo1/', views.ajax_demo1), ... ]
2. AJAX
1. AJAX是什么?
1、简单介绍
我们以前知道的前端向后端发送数据的方式有:
GET:地址栏、a标签、Form表单
POST:Form表单
那么现在我们在学习一种:那就是ajax
ajax:也是前端向后端发送数据的一种方式
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
-
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
Ajax的特点:
异步交互:当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
局部刷新: 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
js的局部刷新:
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
2,AJAX常见应用情景
搜索引擎根据用户输入的关键字,自动提示检索关键字。
还有一个很重要的应用场景就是注册时候的用户名的查重。
其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。
- 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
- 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为lemontree7777777的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。
- 整个过程中页面没有刷新,只是局部刷新了;
- 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
3,AJAX的优缺点
优点:
-
- AJAX使用JavaScript技术向服务器发送异步请求;
- AJAX请求无须刷新整个页面;
- 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;
ajax怎么用
一个请求没有响应我们可以在发送其他请求实例:
html
views
2. jQuery实现的AJAX
jQuery实现的AJAX
最基本的jQuery发送AJAX请求示例:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ajax test</title> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> </head> <body> <button id="ajaxTest">AJAX 测试</button> <script> $("#ajaxTest").click(function () { $.ajax({ url: "/ajax_test/", type: "POST", data: {username: "Q1mi", password: 123456}, success: function (data) { alert(data) } }) }) </script> </body> </html>
views.py:
def ajax_test(request):
user_name =
request.POST.get("username")
password =
request.POST.get("password")
print(user_name, password)
return HttpResponse("OK")
$.ajax参数
data参数中的键值对,如果值值不为字符串,需要将其转换成字符串类型。
$("#b1").on("click", function () { $.ajax({ url:"/ajax_add/", type:"GET", data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])}, success:function (data) { $("#i3").val(data); } }) })
js版ajax
html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <button id="b1">点我 发送 JS 版AJAX请求</button> <script> let b1Ele = document.getElementById("b1"); b1Ele.onclick = function () { // 1. 生成xmlHttp对象 let xmlHttp = new XMLHttpRequest(); // 2. 调用xmlHttp的open方法设置请求相关配置项 xmlHttp.open("POST", "/ajax_js/", true); // 3. 设置请求头 xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 4. 调用send方法发送数据 xmlHttp.send("username=张曌&age=16"); // 5. 处理返回的响应 xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { alert(xmlHttp.responseText); } }; } </script> </body> </html> Views
1,请求参数
######################------------data---------################ data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式 (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。 function testData() { $.ajax("/test",{ //此时的data是一个json形式的对象 data:{ a:1, b:2 } }); //?a=1&b=2 ######################------------processData---------################ processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false, 那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString() ,最后得到一个[object,Object]形式的结果。 ######################------------contentType---------################ contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。 用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据, 比如contentType:"application/json",即向服务器发送一个json字符串: $.ajax("/ajax_get",{ data:JSON.stringify({ a:22, b:33 }), contentType:"application/json", type:"POST", }); //{a: 22, b: 33} 注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象 ######################------------traditional---------################ traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]}, traditional为false会对数据进行深层次迭代;
响应参数
/* dataType: 预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。 默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换; 比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容 进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式 的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用 data Type。 dataType的可用值:html|xml|json|text|script 见下dataType实例 */
实例:
1 from django.shortcuts import render,HttpResponse 2 from django.views.decorators.csrf import csrf_exempt 3 # Create your views here. 4 5 import json 6 7 def login(request): 8 9 return render(request,'Ajax.html') 10 11 12 def ajax_get(request): 13 14 l=['alex','little alex'] 15 dic={"name":"alex","pwd":123} 16 17 #return HttpResponse(l) #元素直接转成字符串alexlittle alex 18 #return HttpResponse(dic) #字典的键直接转成字符串namepwd 19 return HttpResponse(json.dumps(l)) 20 return HttpResponse(json.dumps(dic))# 传到前端的是json字符串,要想使用,需要JSON.parse(data) 21 22 //--------------------------------------------------- 23 function testData() { 24 25 $.ajax('ajax_get', { 26 success: function (data) { 27 console.log(data); 28 console.log(typeof(data)); 29 //console.log(data.name); 30 //JSON.parse(data); 31 //console.log(data.name); 32 }, 33 //dataType:"json", 34 } 35 )} 36 37 注解:Response Headers的content Type为text/html,所以返回的是String;但如果我们想要一个json对象 38 设定dataType:"json"即可,相当于告诉ajax方法把服务器返回的数据转成json对象发送到前端.结果为object 39 当然, 40 return HttpResponse(json.dumps(a),content_type="application/json") 41 42 这样就不需要设定dataType:"json"了。 43 content_type="application/json"和content_type="json"是一样的!
2,ajax的参数补充
- type不写的话默认是GET - dataType和ContentType: dataType: 浏览器发给服务器希望返回的数据类型 。。如果我们明确地指定目标类型,就可以使用data Type。 ContentType: 请求头里有:浏览器告诉服务器内容的类型 响应头里也有:服务器响应浏览器的内容 4、JS和JQuery对象之间的转换 jQuery对象加[0]就转换成了dom对象 dom对象加$符就转换成了jquery对象 5、processDate 默认为True ,预处理; 如果改为False,不做预处理 来自 <http://www.cnblogs.com/haiyan123/p/7829080.html>
3. AJAX优缺点
1. 优点:
局 部更新
异步
2. 缺点:
服务端压力大
4. AJAX处理csrf_token
AJAX请求如何设置csrf_token
方式1
通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。
$.ajax({
url: "/cookie_ajax/",
type: "POST",
data: {
"username":
"Q1mi",
"password": 123456,
"csrfmiddlewaretoken":
$("[name = 'csrfmiddlewaretoken']").val() // 使用JQuery取出csrfmiddlewaretoken的值,拼接到data中
},
success: function (data) {
console.log(data);
}
})
方式2
通过获取返回的cookie中的字符串 放置在请求头中发送。
注意:需要引入一个jquery.cookie.js插件。
一定放jquest后面
$.ajax({
url: "/cookie_ajax/",
type: "POST",
headers: {"X-CSRFToken":
$.cookie('csrftoken')}, // 从Cookie取csrf_token,并设置ajax请求头
data: {"username":
"Q1mi", "password": 123456},
success: function (data) {
console.log(data);
}
})
或者用自己写一个getCookie方法:
function getCookie(name) {
var cookieValue = null;
if (document.cookie &&
document.cookie !== '') {
var cookies =
document.cookie.split(';');
for (var i = 0; i <
cookies.length; i++) {
var cookie =
jQuery.trim(cookies[i]);
// Does this cookie string begin with
the name we want?
if (cookie.substring(0,
name.length + 1) === (name + '=')) {
cookieValue =
decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
每一次都这么写太麻烦了,可以使用$.ajaxSetup()方法为ajax请求统一设置。
function csrfSafeMethod(method)
{
// these HTTP methods do not require
CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type)
&& !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
在前面加上上面自己写的每一次调用导入就行 每一个跟jquest一起导入
来自 <https://www.cnblogs.com/liwenzhou/p/8718861.html>
5. AJAX上传文件
Ajax上传文件(利用FormData):既可以处理二进制,又可以处理字典,列表啊等
FormData是什么呢?
XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.
所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。
注意:下文中的几个需要解释的
$("#upload")
拿到的是一个集合
$("#upload")[0] 就是一个dom对象
$("#upload")[0].files 拿到的是一个filelist
$("#upload")[0].files[0] 拿到的是当前最近的文件对象
要是使用FormData一定要加上:
一定要加上:
contentType:false
processDate:false #不做预处理
ajaxupload.html
!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width"> <title>Title</title> </head> <body> <p>姓名<input type="text" name="username"></p> <p>头像<input type="file" id="upload"></p> <p><button class="btnnn">提交</button><span class="tishi"></span></p> <script src="/static/jquery-3.2.1.min.js"></script> <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script> <script> $(".btnnn").click(function () { var formData=new FormData(); formData.append("username",$(":text").val()); formData.append("file",$("#upload")[0].files[0]); $.ajax({ url:"/get_upload/", type:"POST", headers:{"X-CSRFToken":$.cookie('csrftoken')}, data:formData, contentType:false, processData:false, success:function (data) { $(".tishi").html("上传成功") } }) }) </script> </body> </html>
view.py
def ajaxupload(request): return render(request,"ajaxupload.html") def get_upload(request): if request.method == "POST": print("FIFLE", request.FILES) file_obj = request.FILES.get("file") print(file_obj.name, "-----") file_obj = request.FILES.get("file") with open(file_obj.name, "wb") as f: for i in file_obj: f.write(i) return HttpResponse("上传成功")
实例2
Html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <form action="/upload/" method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="f1"> <input type="submit" value="提交"> </form> <input id="i1" type="file"> <button id="b1">点我</button> <input type="text" id="i2"> <script src="/static/jquery-3.3.1.min.js"></script> <script src="/static/setupAjax.js"></script> <script> $("#b1").click(function () { // 先生成一个表单对象 var formData = new FormData(); // 向form表单对象添加键值对数据 formData.append("f1", $("#i1")[0].files[0]); formData.append("name", "张曌"); $.ajax({ url: "/upload/", type: "POST", processData: false, // 告诉jQuery不要去处理发送的数据 contentType: false, // 告诉jQuery不要去设置Content-Type请求头 data: formData, success:function (data) { console.log(data) } }) }); $("#i2").on("input", function () { console.log($(this).val()) }) </script> </body> </html> Views def upload(request): if request.method == "POST": print(request.POST) file_obj = request.FILES.get("f1") with open(file_obj.name, "wb") as f: for chunk in file_obj.chunks(): f.write(chunk) return HttpResponse("O98K") return render(request, "upload.html")
练习(用户名是否已被注册)
功能介绍
在注册表单中,当用户填写了用户名后,把光标移开后,会自动向服务器发送异步请求。服务器返回这个用户名是否已经被注册过。
案例分析
- 页面中给出注册表单;
- 在username input标签中绑定onblur事件处理函数。
- 当input标签失去焦点后获取 username表单字段的值,向服务端发送AJAX请求;
- django的视图函数中处理该请求,获取username值,判断该用户在数据库中是否被注册,如果被注册了就返回“该用户已被注册”,否则响应“该用户名可以注册”。
3. Django serializer 序列化
serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串。
serialize()函数常用于将表单内容序列化,以便用于AJAX提交。
from django.core import serializers
data = serializers.serialize("json", book_list)
http://www.cnblogs.com/haiyan123/p/7837439.html 可以参考
序列化
Django内置的serializers
def books_json(request):
book_list =
models.Book.objects.all()[0:10]
from django.core
import serializers
ret =
serializers.serialize("json", book_list)
return HttpResponse(ret)
实例:因为前后分离
moderls
class Book(models.Model):
title = models.CharField(max_length=16)
publisher_date = models.DateField()
Views
def books(request):
ret = {"code": 0}
book_list = models.Book.objects.all()
from django.core import serializers
data = serializers.serialize("json", book_list)
ret["data"] = data
return JsonResponse(ret)
def delete_book(request):
if request.method == "POST":
delete_id = request.POST.get("id")
import time
time.sleep(2)
models.Book.objects.filter(id=delete_id).delete()
ret = {"code": 0}
return JsonResponse(ret)
html
<button id="b44">AJAX获取书籍信息</button>
$("#b44").click(function () {
$.ajax({
url: "/books/",
type: "GET",
success: function (data) {
if (data.code === 0) {
console.log(data.data);
}
}
})
});
4. 补充
,1, ECHARTS 划图工具 统计代码图
一定放在jquest后面
Views
Html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>echarts demo</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>echarts demo</h1> <div id="main" style="width: 600px;height:400px;"></div> <script src="/static/jquery-3.3.1.min.js"></script> <script src="/static/echarts.simple.min.js"></script> <script> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); // 使用AJAX向后端请求数据 $.ajax({ url: "/demo/", type: "POST", data: {name: "长牙签"}, success: function (data) { // 指定图表的配置项和数据 var option = { title: { text: 'ECharts 入门示例' }, tooltip: {}, legend: { data: ['代码量'] }, xAxis: { data: data.date }, yAxis: {}, series: [{ name: '代码量', type: 'bar', data: data.code_amount }] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); } }); </script> </body> </html>
2,SweetAlert补充一个SweetAlert插件示例
弹出:
$(".btn-danger").on("click", function () { swal({ title: "你确定要删除吗?", text: "删除可就找不回来了哦!", type: "warning", showCancelButton: true, confirmButtonClass: "btn-danger", confirmButtonText: "删除", cancelButtonText: "取消", closeOnConfirm: false }, function () { var deleteId = $(this).parent().parent().attr("data_id"); $.ajax({ url: "/delete_book/", type: "post", data: {"id": deleteId}, success: function (data) { if (data.status === 1) { swal("删除成功!", "你可以准备跑路了!", "success"); } else { swal("删除失败", "你可以再尝试一下!", "error") } } }) }); })
2. 写一个用户名查重的功能 input事件
用AJAX写一个登陆,登陆成功之后跳转到路飞学成官网
来源:https://www.cnblogs.com/maojiang/p/9235880.html