058.Python前端Django与Ajax

python

一 Ajax简介

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

优点:

  1. AJAX使用Javascript技术向服务器发送异步请求
  2. AJAX无须刷新整个页面

二 AJAX的异步请求

设计路由

from django.contrib import admin

from django.urls import path

from app01 import views

urlpatterns = [

path('admin/', admin.site.urls),

path('add_book/',views.add_book),

path('query_book/',views.query_book),

#ajax相关

path('ajax_sleep/',views.ajax_sleep),

path('ajax_test/',views.ajax_test),

#前端页面

path('ajax_temp/',views.ajax_temp),

]

views视图文件

def ajax_sleep(request):

import time

time.sleep(3)

return HttpResponse("sleep 3 senond")

def ajax_test(request):

return HttpResponse("test...")

def ajax_temp(request):

return render(request,"ajax_temp.html")

html文件

root@darren-virtual-machine:~/PycharmProjects/orm_demo# vim templates/ajax_temp.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<body>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

$("#btn1").click(function () {

$.ajax({

url:"/ajax_sleep/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

$("#btn2").click(function () {

$.ajax({

url:"/ajax_test/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

</script>>

</body>

</html>

访问http://127.0.0.1:8000/ajax_temp/,先点击ajax_sleep然后点击test,这时在sleep中间正在执sleep代码,但是在点击test,也会执行,先于sleep输出,说明是一个异步操作,同时点击test后,页面并不会刷新,是一个局部刷新的动作

三 实现ajax的一个计算案例

制作一个如下页面,当在前面输入两个数字,点击提交触发后,会把结果填在第三个框里

设计路由

from django.contrib import admin

from django.urls import path

from app01 import views

urlpatterns = [

path('admin/', admin.site.urls),

path('add_book/',views.add_book),

path('query_book/',views.query_book),

#ajax相关

path('ajax_sleep/',views.ajax_sleep),

path('ajax_test/',views.ajax_test),

#前端页面

path('ajax_temp/',views.ajax_temp),

#ajax求和

path('ajax_sum/',views.ajax_sum),

]

view视图

def ajax_sum(request):

if request.is_ajax():

num1 = request.POST.get("num1")

num2 = request.POST.get("num2")

total = int(num1) + int(num2)

return HttpResponse(total)

html 

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button>

</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

$("#btn1").click(function () {

$.ajax({

url:"/ajax_sleep/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

$("#btn2").click(function () {

$.ajax({

url:"/ajax_test/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

},

success:function (data) {

$("#i3").val(data);

}

})

})

</script>

</body>

</html>

访问http://127.0.0.1:8000/ajax_temp/

 

403报错

是由于crfs影响,添加crfs

修改html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button>

</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},

success:function (data) {

$("#i3").val(data);

}

})

})

</script>

</body>

</html>

再次访问,并输入计算值,点击计算

 ajax请求流程

当输入非数字计算

调试信息

  File "/root/PycharmProjects/orm_demo/app01/views.py", line 131, in ajax_sum

total = int(num1) + int(num2)

ValueError: invalid literal for int() with base 10: 'qq'

[08/Apr/2020 03:48:19] "POST /ajax_sum/ HTTP/1.1" 500 14677

view视图文件

from django.shortcuts import render,HttpResponse

from app01 import models

from django.http import JsonResponse

def ajax_sum(request):

if request.is_ajax():

num1 = request.POST.get("num1")

num2 = request.POST.get("num2")

ret = {"status":1,"msg":None}

try:

total = int(num1) + int(num2)

ret["msg"] = total

except Exception as e:

ret['status'] = 0

ret["msg"] = "请输入数字"

#需要使用到数据结构,使用json方式传过去,先要导入jsonhttponse

return JsonResponse(ret)

html调整

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button><span >> {#多加一个span标签#}

</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},
        {#默认传输的值是1,就会把传过来的msg值输入,挡status值为0时,就会把自定义的提示显示,和view视图文件对应#}

success:function (data) {

if (data.status){

$("#i3").val(data.msg);

}else{

$("#s1").text(data.msg);

}

}

})

})

</script>

</body>

</html>

输入非数字时,会有提示

问题,当再次输入正确格式,提示不会小时,

使用定时器解决,显示2秒后消失

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>

</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},

success:function (data) {

if (data.status){

$("#i3").val(data.msg);

}else{

$("#s1").text(data.msg);

setTimeout(function () {

$("#s1").text("");

},2000)

}

}

})

})

</script>

</body>

</html>

访问后,输入错误值,两秒后消失

四 基于Ajax上传json数据

url设计

from django.contrib import admin

from django.urls import path

from app01 import views

urlpatterns = [

path('admin/', admin.site.urls),

path('add_book/',views.add_book),

path('query_book/',views.query_book),

#ajax相关

path('ajax_sleep/',views.ajax_sleep),

path('ajax_test/',views.ajax_test),

#前端页面

path('ajax_temp/',views.ajax_temp),

#ajax求和

path('ajax_sum/',views.ajax_sum),

#ajax上传json数据

path('ajax_json/',views.ajax_json),

]

views视图文件

视图响应时,必须是HttpResponse 或者 HttpResponse,不能是render或者redict

def ajax_json(request):

import json

print(request.POST)

print(request.body)

data = json.loads(request.body.decode())

print(data)

return HttpResponse("Ok")

html文件

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

<button id="btn4">上传json数据</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>

</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 异步案例 #}

$("#btn1").click(function () {

$.ajax({

url:"/ajax_sleep/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

$("#btn2").click(function () {

$.ajax({

url:"/ajax_test/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},

success:function (data) {

if (data.status){

$("#i3").val(data.msg);

}else{

$("#s1").text(data.msg);

setTimeout(function () {

$("#s1").text("");

},2000)

}

}

})

});

$("#btn4").click(function () {

$.ajax({

url:"/ajax_json/",

type: "POST",

contentType:"json",

headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf

data: JSON.stringify({

a:100,

b:200,

user:"darren",

}),

success:function (data) {

console.log(data)

}

})

})

</script>

</body>

</html>

访问点击提交json数据

得到结果

调试输出

<QueryDict: {}>

b'{"a":100,"b":200,"user":"darren"}'

{'a': 100, 'b': 200, 'user': 'darren'}

在使用视图文件时,当使用HttpResponse返回时,前端代码需要使用json的数据,必须需要使用JSON.parse(data){}反序列化才能使用

当使用JsonResponse(ret)返回时,可以直接使用,例如sum案例

五 基于form表单上传文件

下载一张图片到桌面备用,test111.png

url文件

from django.contrib import admin

from django.urls import path

from app01 import views

urlpatterns = [

path('admin/', admin.site.urls),

path('add_book/',views.add_book),

path('query_book/',views.query_book),

#ajax相关

path('ajax_sleep/',views.ajax_sleep),

path('ajax_test/',views.ajax_test),

#前端页面

path('ajax_temp/',views.ajax_temp),

#ajax求和

path('ajax_sum/',views.ajax_sum),

#ajax上传json数据

path('ajax_json/',views.ajax_json),

#form表单上传

path('upload/',views.upload),

]

views

import  os

def upload(request):

if request.method == "POST":

print(request.POST)

print(request.FILES)

#print(request.body) 报错

file_obj = request.FILES.get('file_name')

name = file_obj.name

with open(os.path.join("media", name), "wb") as f:

for i in file_obj:

f.write(i)

return HttpResponse('上传成功')

html写一个form表单

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

<button id="btn4">上传json数据</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>

</div>

<hr>

<h3>form表单上传文件</h3>

<form action="/upload/" method="POST" enctype="multipart/form-data">

{% csrf_token %}

<input type="text" name="user">

<input type="file" name="file_name">

<input type="submit">

</form>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 异步案例 #}

$("#btn1").click(function () {

$.ajax({

url:"/ajax_sleep/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

$("#btn2").click(function () {

$.ajax({

url:"/ajax_test/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},

success:function (data) {

if (data.status){

$("#i3").val(data.msg);

}else{

$("#s1").text(data.msg);

setTimeout(function () {

$("#s1").text("");

},2000)

}

}

})

});

$("#btn4").click(function () {

$.ajax({

url:"/ajax_json/",

type: "POST",

contentType:"json",

headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf

data: JSON.stringify({

a:100,

b:200,

user:"darren",

}),

success:function (data) {

console.log(data)

}

})

})

</script>

</body>

</html>

root@darren-virtual-machine:~/PycharmProjects/orm_demo# mkdir media

访问,选择文件

点击submit,上传成功

调试输出

<QueryDict: {'csrfmiddlewaretoken': ['JA1GUiIv2LZCvSTxFjP8IOMaW7MNb3q3tjI5nOtFyXv6RETZxqq729rBOTFlFkE5'], 'user': ['']}>

<MultiValueDict: {'file_name': [<InMemoryUploadedFile: test111.jpeg (image/jpeg)>]}>

服务器查看

root@darren-virtual-machine:~/PycharmProjects/orm_demo# ll media/

六 基于Ajax请求上传文件

修改html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

<button id="btn4">上传json数据</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>

</div>

<hr>

<h3>form表单上传文件</h3>

{# <form action="/upload/" method="POST" enctype="multipart/form-data"> #}

{% csrf_token %}

<input type="text" id="user" name="user">

<input type="file" id="file1" name="file_name">

<button id="btn5">ajax上传文件</button>

{# <input type="submit"> #}

{# </form> #}

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 异步案例 #}

$("#btn1").click(function () {

$.ajax({

url:"/ajax_sleep/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

$("#btn2").click(function () {

$.ajax({

url:"/ajax_test/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},

success:function (data) {

if (data.status){

$("#i3").val(data.msg);

}else{

$("#s1").text(data.msg);

setTimeout(function () {

$("#s1").text("");

},2000)

}

}

})

});

$("#btn4").click(function () {

$.ajax({

url:"/ajax_json/",

type: "POST",

contentType:"json",

headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf

data: JSON.stringify({

a:100,

b:200,

user:"darren",

}),

success:function (data) {

console.log(data)

}

})

})

</script>

</body>

</html>

调试

添加ajax

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<button id="btn1">ajax_sleep</button>

<button id="btn2">ajax_test</button>

<button id="btn4">上传json数据</button>

{% csrf_token %}

<hr>

<div>

<input type="text" id="i1"> + <input type="text" id="i2"> =

<input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>

</div>

<hr>

<h3>form表单上传文件</h3>

{# <form action="/upload/" method="POST" enctype="multipart/form-data"> #}

{% csrf_token %}

<input type="text" id="user" name="user">

<input type="file" id="file1" name="file_name">

<button id="btn5">ajax上传文件</button>

{# <input type="submit"> #}

{# </form> #}

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

{# 异步案例 #}

$("#btn1").click(function () {

$.ajax({

url:"/ajax_sleep/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

$("#btn2").click(function () {

$.ajax({

url:"/ajax_test/",

type:"GET",

success:function (data) {

console.log(data);

}

}

)

})

{# 计算案例 #}

$('#btn3').click(function () {

var num1 = $("#i1").val();

var num2 = $("#i2").val();

$.ajax({

url: "/ajax_sum/",

type: "POST",

data:{

num1:num1,

num2:num2,

csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),

},

success:function (data) {

if (data.status){

$("#i3").val(data.msg);

}else{

$("#s1").text(data.msg);

setTimeout(function () {

$("#s1").text("");

},2000)

}

}

})

});

$("#btn4").click(function () {

$.ajax({

url:"/ajax_json/",

type: "POST",

contentType:"json",

headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf

data: JSON.stringify({

a:100,

b:200,

user:"darren",

}),

success:function (data) {

console.log(data)

}

})

})

{# ajax上传文件 #}

$("#btn5").click(function () {

var formdata = new FormData();

formdata.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());

formdata.append("file_name",$("#file1")[0].files[0]);

$.ajax({

url: "/upload/",

type: "POST",

processData: false, // 告诉jQuery不要去处理发送的数据

contentType: false, // 告诉jQuery不要去设置Content-Type请求头

data: formdata,

success:function (data) {

console.log(data)

}

})

})

</script>

</body>

</html>

修改图片名为test222

点击ajax上传文件

检查服务器文件

root@darren-virtual-machine:~/PycharmProjects/orm_demo# ll media/

七 请求头ContentType

ContentType指的是请求体的编码类型,常见的类型共有3种:

  1.  application/x-www-form-urlencoded应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。
  2.  multipart/form-data是另一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。
  3.  application/json:这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。 

 

以上是 058.Python前端Django与Ajax 的全部内容, 来源链接: utcz.com/z/388843.html

回到顶部