Django如何与Ajax交互


Posted in Python onApril 29, 2021

前后端传输数据的编码格式

前后端传输数据的编码格式主要有三种, 本文接下来将详细演示。

urlencoded
formdata
json

Ajax提交urlencoded格式数据

Ajax给后台发送数据的默认编码格式是urlencoded,比如username=abcde&password=123456的形式。Django后端拿到符合urlencoded编码格式的数据都会自动帮你解析分装到request.POST中,与form表单提交的数据相同。

下面两种方式是等同的。

//手动构造数据data
$("#btnSubmit").click(function () {
    $.ajax({
        url: '/auth/', //也可以反向解析{% url 'login' %}
        type: 'post',
        data: {
            'username': $("#id_username").val(),
            'password': $('#id_password').val()
        },
        success: function (data){
            
        }
    });
};
                    
// .serialize() 方法可将<input>, <textarea> 以及 <select>表单序列化
// 成urlencoded格式数据
                      
$("#btnSubmit").click(function () {
    let data = $("#loginForm").serialize();
    $.ajax({
        url: "/auth/", //别忘了加斜杠
        type: $("#loginForm").attr('method'),
        data: data,
        success: function (data) {
         
        }
    });
});

Ajax通过FormData上传文件

Ajax上传文件需要借助于js内置对象FormData,另外上传文件时表单千万别忘了加enctype="multipart/form-data"属性。

//案例1,点击submi上传文件
$("#submitFile").click(function () {
    let formData = new FormData($("#upload-form"));
    $.ajax({
       url:"/upload/",//也可以写{% url 'upload' %}
       type:"post",
       data:formData,
       //这两个要必须写
       processData:false,  //不预处理数据  因为FormData 已经做了
       contentType:false,  //不指定编码了 因为FormData 已经做了
       success:function(data){
             console.log(data);
       }
    });
});
                       
//案例2,同时上传文件并提交其它数据
$("#submitFile").click(function () {
    //js取到文件
    let myfile = $("#id_file")[0].files[0];
    //生成一个FormData对象
    let formdata = new FormData();
    //加值
    formdata.append('name', $("#id_name").val());
    //加文件
    formdata.append('myfile', myfile);
    $.ajax({
        url: '/upload/', //url别忘了加/杠
        type: 'post',
        //这两个要必须写
        processData:false,  //不预处理数据  因为FormData 已经做了
        contentType:false,  //不指定编码了 因为FormData 已经做了
        data: formdata,
        success: function (data) {
            console.log(data);
        }
    });
});

Ajax提交Json格式数据

前后端传输数据的时候一定要确保声明的编码格式跟数据真正的格式是一致的。如果你通过Ajax发送Json格式数据给Django后端,请一定注意以下三点:

  1. contentType参数指定成application/json;
  2. 数据是真正的json格式数据;
  3. Django后端不会帮你处理json格式数据需要你自己去request.body获取并处理。
$("#submitBtn").click(function () {
    var data_obj={'name':'abcdef','password':123456};//Javascript对象
    $.ajax({
        url:'',
        type:'post',
        contentType:'application/json',  //一定要指定格式 contentType
        data:JSON.stringify(data_obj),    //转换成json字符串格式
        success:function (data) {
            console.log(data)
        }
    });
});

Ajax发送POST请求时如何通过CSRF认证

// 第一种方式直接在发送数据中加入csrfmiddlewaretoken
$("#btn").on("click",function () {
    $.ajax({
        url:"/some_url/",
        type:"POST",
        data:{
            csrfmiddlewaretoken: {{ csrf_token }}, //写在模板中,才会被渲染
        },
        success:function (data) {
    }
});
});
 
//通过jquery选择器获取csrfmiddlewaretoken
$("#btn").on("click",function () {
    $.ajax({
        url:"/some_url/",
        type:"POST",
        data:{
            csrfmiddlewaretoken:$('[name="csrfmiddlewaretoken"]').val(),
        },
        success:function (data) {
            
        }
    });
});
 
//使用jquery.cookie.js调用请求头cookie中的csrftoken
<script src="/static/jquery.cookie.js"> 
<script>
     $("#btn").on("click",function () {
     $.ajax({
        url:"/some_url/",
        type:"POST",
        headers:{"X-CSRFToken":$.cookie('csrftoken')},
        data:$("#form1").serialize()
    });
   })
</script>

Django Ajax案例1:联动下例菜单

联动下拉菜单是Web开发中一个被经常使用的应用。比如当你从一个列表从选择一个国家的时候,联动下拉菜单会同步显示属于该国家所有城市列表供用户选择。今天我们就教你如何使用Django+Ajax生成联动下拉菜单。

我们的模型如下所示:

class Country(models.Model):
    name = models.CharField(verbose_name="国家", max_length=50)

    def __str__(self):
        return self.name


class City(models.Model):
    name = models.CharField(verbose_name="城市", max_length=50)
    country = models.ForeignKey(Country, on_delete=models.CASCADE, verbose_name="国家",)

    def __str__(self):
        return self.name

我们的模板如下所示,表单中对应国家和城市下拉菜单的DOM元素id分别为id_country和id_city。当用户选择国家后,ajax会携带国家的id值向后台发送请求获得当前国家的所有城市清单,并在前端渲染显示。

{% block content %}
<h2>创建用户 - 联动下拉菜单</h2>
<form method="post" class="form-horizontal" role='form' action="">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}

<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
    $("#id_country").change(function() {
      var country_id = $(this).val();

      $.ajax({
        url: '/ajax/load_cities/',
        data: {
          'country_id': country_id
        },
        type: 'GET',
        dataType: 'json',
        success: function (data) {
            var content='';
            $.each(data, function(i, item){
                  content+='<option value='+item.id+'>'+item.name+'</option>'
                });
            $('#id_city').html(content)
        },

      });
    });
  </script>

Django负责处理视图Ajax请求的视图函数如下所示:

def ajax_load_cities(request):
    if request.method == 'GET':
        country_id = request.GET.get('country_id', None)
        if country_id:
            data = list(City.objects.filter(country_id=country_id).values("id", "name"))
            return JsonResponse(data, safe=False)

Django Ajax案例2:Ajax上传文件

前端模板及js文件如下所示, 请注意我们是如何在表单中加入了enctype属性,如何使用FormData上传文件,并解决了csrftoken问题的。

{% block content %}
<form action="" method="post" enctype="multipart/form-data" id="form">
    <ul class="errorlist"></ul>
    {% csrf_token %}
{{ form.as_p }}
 <input type="button" class="btn btn-info form-control" value="submit" id="btn" />
</form>
<table class="table table-striped" id="result">
</table>
{% endblock %}

{% block js %}
<script src=" https://cdn.jsdelivr.net/jquery.cookie/1.4.1/jquery.cookie.min.js ">
</script>
<script>
var csrftoken = $.cookie('csrftoken');
function csrfSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$(document).ready(function(){
   $('#btn').click(function(e){
        e.preventDefault();
        // 构建FormData对象
        var form_data = new FormData();
        form_data.append('file', $('#id_file')[0].files[0]);
        $.ajax({
        url: '/file/ajax_upload/',
        data: form_data,
        type: 'POST',
        dataType: 'json',
        // 告诉jQuery不要去处理发送的数据, 发送对象。
        processData : false,
        // 告诉jQuery不要去设置Content-Type请求头
        contentType : false,
        // 获取POST所需的csrftoken
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }},
        success: function (data) {
            if(data['error_msg']) {
                var content = '<li>'+ data['error_msg'] + '</li>';
                $('ul.errorlist').html(content);
            }
            else
            {
            var content= '<thead><tr>' +
            '<th>Name and URL</th>' +
            '<th>Size</th>' +
            '</tr></thead><tbody>';
             $.each(data, function(i, item) {
                  content = content +
                  '<tr><td>' +
                  "<a href= ' " +
                  item['url'] +
                  " '> " +
                  item['url'] +
                  '</a></td><td>' +
                  item['size'] +
                  '</td><td><tr>'
                });
             content = content + "</tbody>";
             $('#result').html(content);
             }
           },
        });
   });
 });
  </script>
{% endblock %}

Django负责处理视图Ajax请求的视图函数如下所示:

# handling AJAX requests
def ajax_upload(request):
    if request.method == "POST":
        form = FileUploadModelForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            form.save()
            # Obtain the latest file list
            files = File.objects.all().order_by('-id')
            data = []
            for file in files:
                data.append({
                    "url": file.file.url,
                    "size": filesizeformat(file.file.size),
                    })
            return JsonResponse(data, safe=False)
        else:
            data = {'error_msg': "Only jpg, pdf and xlsx files are allowed."}
            return JsonResponse(data)
    return JsonResponse({'error_msg': 'only POST method accpeted.'})

以上就是Django如何与Ajax交互的详细内容,更多关于Django与Ajax交互的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
教你用 Python 实现微信跳一跳(Mac+iOS版)
Jan 04 Python
python+selenium打印当前页面的titl和url方法
Jun 22 Python
使用PIL(Python-Imaging)反转图像的颜色方法
Jan 24 Python
Python实现删除排序数组中重复项的两种方法示例
Jan 31 Python
python适合人工智能的理由和优势
Jun 28 Python
python线程定时器Timer实现原理解析
Nov 30 Python
python torch.utils.data.DataLoader使用方法
Apr 02 Python
python实现逢七拍腿小游戏的思路详解
May 26 Python
numpy的Fancy Indexing和array比较详解
Jun 11 Python
python对批量WAV音频进行等长分割的方法实现
Sep 25 Python
如何在scrapy中捕获并处理各种异常
Sep 28 Python
Python文件名匹配与文件复制的实现
Dec 11 Python
Python爬虫进阶之Beautiful Soup库详解
Apr 29 #Python
win10+anaconda安装yolov5的方法及问题解决方案
Python图像处理之图像拼接
4种非常实用的python内置数据结构
Apr 28 #Python
Python基础详解之描述符
Apr 28 #Python
详解Python 3.10 中的新功能和变化
Apr 28 #Python
Python基础之数据结构详解
Apr 28 #Python
You might like
PHP常量使用的几个需要注意的地方(谨慎使用PHP中的常量)
2014/09/12 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
在IE下获取object(ActiveX)的Param的代码
2009/09/15 Javascript
使用JavaScript switch case 另类写法
2010/03/14 Javascript
javascript 类型判断代码分析
2010/03/28 Javascript
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
Javascript判断对象是否相等实现代码
2013/03/18 Javascript
JavaScript将当前时间转换成UTC标准时间的方法
2015/04/06 Javascript
js字符串操作方法实例分析
2015/05/06 Javascript
JavaScript实现网页加载进度条代码超简单
2015/09/21 Javascript
DropDownList控件绑定数据源的三种方法
2016/12/24 Javascript
javascript 中的try catch应用总结
2017/04/01 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
2017/11/14 Javascript
vue 根据数组中某一项的值进行排序的方法
2018/08/30 Javascript
详解Vue.js iview实现树形权限表(可扩展表)
2018/09/30 Javascript
node.JS二进制操作模块buffer对象使用方法详解
2020/02/06 Javascript
Flask入门之上传文件到服务器的方法示例
2018/07/18 Python
Python查找数组中数值和下标相等的元素示例【二分查找】
2019/02/13 Python
利用python计算windows全盘文件md5值的脚本
2019/07/27 Python
Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例
2020/02/11 Python
python学生管理系统的实现
2020/04/05 Python
python从PDF中提取数据的示例
2020/10/30 Python
jupyter notebook 写代码自动补全的实现
2020/11/02 Python
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
Ryderwear美国官网:澳大利亚高端健身训练装备品牌
2018/04/24 全球购物
英语专业推荐信
2013/11/16 职场文书
政法大学毕业生自荐信范文
2014/01/01 职场文书
高中军训感言400字
2014/02/24 职场文书
交通文明倡议书
2014/05/16 职场文书
团日活动总结模板
2014/06/25 职场文书
药品销售内勤岗位职责
2015/04/13 职场文书
党员公开承诺书2016
2016/03/24 职场文书
导游词之香港-太平山顶
2019/10/18 职场文书
使用Redis做预定库存缓存功能
2022/04/02 Redis