Django与Ajax
一、关于Ajax
1、概念:Ajax翻译成中文就是异步Javascript和XML,即使用JAvascript语言与服务器进行异步交互,传输的数据XML,当然传输的不只是XML,现在更多使用的是jsaon数据。
2、异步:请求发出去,不会卡在这里,可以干其他的事情。
3、局部刷新:js的dom操作,使页面局部刷新。
4、基本上web页面有很多ajax请求。
二、ajax与后端交互-发送get请求
现在比较主流做法,jquery(前后端混合),axios(前后端分离)
🌼 简单案例:
一、ajax发送get请求
视图层:
from django.shortcuts import render
from django.http import JsonResponse
def ajax_get(request):
return render(request,'ajax_get.html')
def ajax_sum(request):
a1=request.GET.get('a1')
a2=request.GET.get('a2')
sum=int(a1)+int(a2)
return JsonResponse(sum,safe=False)
模版层
<body>
<input type="text" id="s1" name="a1">+ <input type="text" id="s2" name="a2">= <input type="text" id="sum">
<p><button id="s4">计算</button></p>
</body>
<script>
$('#s4').click(function(){
$.ajax({
url:'/ajax_sum/',
method:'get',
data:{a1:$('#s1').val(),a2:$('#s2').val()},
success:function (data) {
$('#sum').val(data)
}
})
})
</script>
ajax发送其他请求
视图层
def ajax_login(request):
if request.method=='GET':
return render(request,'ajax_login.html')
username=request.POST.get('username')
password=request.POST.get('password')
if username=='judy' and password=='123':
return JsonResponse('登入成功',safe=False)
return JsonResponse('用户名或密码错误',safe=False)
模版层
<body>
<p>username: <input type="text" id="s1"></p>
<p>password: <input type="text" id="s2"></p>
<br>
<button class="user_btn">提交</button> <span id="s4"></span>
</body>
<script>
$('.user_btn').click(function (){
$.ajax({
url:'/ajax_login/',
method:'post',
data:{username:$('s1').val(),password:$('s2').val(),csrfmiddlewaretoken:'{{ csrf_token}}'},
success:function (data){
$('#s4').html(data)
console.log(data)
}
})
})
</script>
注意事项
1、如果在form表单中,写button或者input是submit类型就会触发form表单的提交,如果不想触发有两种解决方案,第一可以不要写在form表单中,第二使用input但是类型选择button
2、如果后端相应格式是html/text格式,ajax接收到数据后需要自己转成对象,后端如果响应格式是json格式,ajax会接收到数据自动转成对象。总结:后端返回数据的时候统一使用JASONRESPONSE。
3、一旦使用了ajaz,是能是字符串或者jsaon格式,其他都是不能使用的。
上传文件
知识补充
1、http post请求,有编码格式,主流的有三种:
-urlencoded 默认的-->从request.POST提取数据
-form-data 上传文件-->从request.POST提取数据,从request.FILES中取文件
-json ajax发送json格式-->rquest.POST取不到数据
🌼简单案例
视图层
def ajax_files(request):
if request.method == 'GET':
return render(request, 'ajax_file.html')
if request.is_ajax():
my_data = request.FILES.get('my_file')
with open('xxx', 'wb') as f:
for line in my_data:
f.write(line)
return JsonResponse('上传文件成功', safe=False)
模版层
<body>
<input type="file" class="s1">
<br>
<button class="btn_file">提交</button>
</body>
<script>
$('.btn_file').click(function () {
var form_data = new FormData() # ajax上传文件需要借助FormData,先实例化。然后将数据都append到实力话得到的对象中去。
var my_file = $('.s1')[0].files[0] #取文件
form_data.append('my_file', my_file) #往对象加文件
form_data.append('csrfmiddlewaretoken', '{{ csrf_token}}') # 处理csrf跨站请求
$.ajax({
url: 'ajax_files',
method: 'post',
processData: false, #上传文件必须加这两句话,第一句是不要预处理数据,第二句是不指定请求编码
contentType: false,
data: form_data,
success: function (data) {
console.log(data)
}
})
})
</script>
ajax结合layer弹窗实现二次确认
🌼简单案例
视图层
def ajax_layer(request):
if request.method=='GET':
data=models.User.objects.all()
return render(request,'ajax_layer.html',locals())
if request.is_ajax():
dic={'status':200,'msg':'删除数据成功'}
id=request.POST.get('id')
models.User.objects.filter(pk=id).delete()
return JsonResponse(dic)
模版层
<body>
<div class="container">
<div class="row">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>id</th>
<th>username</th>
<th>password</th>
<th>操作</th>
</tr>
<tbody>
{% for dic in data %}
<tr>
<td>{{ dic.id }}</td>
<td>{{ dic.username }}</td>
<td>{{ dic.password }}</td>
<td><a class="button" id="btn_"{{ dic.id }} onclick="del_user({{ dic.id }})">删除</a></td>
</tr>
{% endfor %}
</tbody>
</thead>
</table>
</div>
</div>
</body>
<script>
function del_user(id) {
layer.confirm('你确定要删除吗', {
btn: ['yes', 'no'],
}, function () {
$.ajax({
url: '/ajax_layer/',
method: 'post',
data: {'id': id, 'csrfmiddlewaretoken': '{{ csrf_token}}'},
success: function (data) {
console.log(data)
if (data.status == 200) {
layer.msg(data.msg)
{#layer.alert(data.msg)#}
location.reload()
{# 重新加载页面 #}
}
}
})
})
}
</script>
ajax发送json数据
🌼 前端发送
$.ajax({
type:"POST",
url:"/panorama/saveScene",
processData: false,
contentType: "application/json;charset=utf-8", //这个是发送信息至服务器时内容编码类型
dataType: "json",
data:JSON.stringify(xml_data),//这里必须将对象转成string类型,否则将掉入无线的大坑中。。。
success:function(msg){
alert(msg);
}
})
🌼 后端接收
后端接收要利用request.body接收
为此我们可以写一个装饰器
def outer(func):
def inner(request,*args,**kwargs):
try:
request.data=json.loads(request.body)
except Exception as e:
request.data=request.POST
res=func(request,*args,**kwargs)
return res
return inner
这样的话,不管数据是射从request.body中拿还是从request.POST中拿,我们统一从request.data拿即可。
浙公网安备 33010602011771号