How does Django interact with Ajax

  • 2021-11-02 01:51:26
  • OfStack

Encoding format of data transmitted at the front and back ends of the directory
Ajax Submits urlencoded Format Data
Ajax uploads files via FormData
Ajax Submits Json Format Data
How does Ajax authenticate Django Ajax through CSRF when sending POST request Case 1: Linkage with the following example menu
Django Ajax Case 2: Ajax Upload File

Encoding format of front-end and back-end transmission data

There are three main coding formats for data transmission at the front and back ends, which will be demonstrated in detail next in this paper.


urlencoded
formdata
json

Ajax Submit urlencoded Format Data

The default encoding format for Ajax to send data to the background is urlencoded, for example, username=abcde & password=123456. The data obtained by Django backend in accordance with urlencoded encoding format will be automatically parsed and packaged into request. POST, which is the same as the data submitted by form form.

The following two ways are equivalent.


// Construct data manually data
$("#btnSubmit").click(function () {
    $.ajax({
        url: '/auth/', // It can also be resolved in reverse {% url 'login' %}
        type: 'post',
        data: {
            'username': $("#id_username").val(),
            'password': $('#id_password').val()
        },
        success: function (data){
            
        }
    }) ; 
} ; 
                    
// .serialize()  Method can set the <input>, <textarea>  As well as  <select> Form serialization 
//  Cheng urlencoded Format data 
                      
$("#btnSubmit").click(function () {
    let data = $("#loginForm").serialize();
    $.ajax({
        url: "/auth/", // Don't forget to add slashes 
        type: $("#loginForm").attr('method'),
        data: data,
        success: function (data) {
         
        }
    });
}); 

Ajax Upload files via FormData

Ajax uploading files requires the help of js built-in object FormData. In addition, when uploading files, don't forget to add enctype= "multipart/form-data" attribute to the form.


// Case 1 , click submi Upload a file 
$("#submitFile").click(function () {
    let formData = new FormData($("#upload-form"));
    $.ajax({
       url:"/upload/",// You can also write {% url 'upload' %}
       type:"post",
       data:formData,
       // These two must be written 
       processData:false,  // Do not preprocess data    Because FormData  It has been done 
       contentType:false,  // No code is specified   Because FormData  It has been done 
       success:function(data){
             console.log(data);
       }
    });
});
                       
// Case 2, Upload files and submit other data at the same time 
$("#submitFile").click(function () {
    //js Fetch a file 
    let myfile = $("#id_file")[0].files[0];
    // Generate 1 A FormData Object 
    let formdata = new FormData();
    // Bonus 
    formdata.append('name', $("#id_name").val());
    // Add files 
    formdata.append('myfile', myfile);
    $.ajax({
        url: '/upload/', //url Don't forget to add / Bar 
        type: 'post',
        // These two must be written 
        processData:false,  // Do not preprocess data    Because FormData  It has been done 
        contentType:false,  // No code is specified   Because FormData  It has been done 
        data: formdata,
        success: function (data) {
            console.log(data);
        }
    });
}); 

Ajax Submit Json Format Data

When transmitting data between front and back end, 1 make sure that the declared encoding format and the true format of the data are 1. If you send Json format data to the Django backend via Ajax, please pay attention to the following three points:

The contentType parameter is specified as application/json; The data is true json format data; The Django backend will not help you process json format data. You need to go to request. body to get and process it yourself.

$("#submitBtn").click(function () {
    var data_obj={'name':'abcdef','password':123456};//Javascript Object 
    $.ajax({
        url:'',
        type:'post',
        contentType:'application/json',  //1 Be sure to specify the format  contentType
        data:JSON.stringify(data_obj),    // Convert to json String format 
        success:function (data) {
            console.log(data)
        }
    });
});

How to pass CSRF authentication when Ajax sends POST request


//  No. 1 1 Add to the sent data directly in one way or another csrfmiddlewaretoken
$("#btn").on("click",function () {
    $.ajax({
        url:"/some_url/",
        type:"POST",
        data:{
            csrfmiddlewaretoken: {{ csrf_token }}, // Write in the template before it will be rendered 
        },
        success:function (data) {
    }
});
});
 
// Pass jquery Selector acquisition csrfmiddlewaretoken
$("#btn").on("click",function () {
    $.ajax({
        url:"/some_url/",
        type:"POST",
        data:{
            csrfmiddlewaretoken:$('[name="csrfmiddlewaretoken"]').val(),
        },
        success:function (data) {
            
        }
    });
});
 
// Use jquery.cookie.js Call request header cookie In 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 Case 1: Linkage the following example menu

Linkage drop-down menu is a frequently used application in Web development. For example, when you select a country from a list, the linkage drop-down menu will simultaneously display a list of all cities belonging to that country for users to choose from. Today we'll show you how to use Django + Ajax to generate linkage drop-down menus.

Our model is as follows:


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

    def __str__(self):
        return self.name


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

    def __str__(self):
        return self.name

Our template is shown below, and the DOM elements id corresponding to the country and city drop-down menus in the form are id_country and id_city, respectively. When the user selects the country, ajax will send a request to the background with the id value of the country to obtain the list of all cities in the current country, and render it in the front end.


{% block content %}
<h2> Create a user  -  Linkage drop-down menu </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>

The view function that Django handles requests from the view Ajax is as follows:


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 Case 2: Ajax Upload File

The front-end template and js file are shown below. Please notice how we added enctype attribute to the form, how we uploaded files using FormData, and solved csrftoken problem.


{% 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();
        //  Build FormData Object 
        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',
        //  Tell jQuery Don't deal with the data sent ,  Send the object. 
        processData : false,
        //  Tell jQuery Don't set Content-Type Request header 
        contentType : false,
        //  Get POST Required 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 %}

The view function that Django handles requests from the view Ajax is as follows:


# 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.'})

These are the details of how Django interacts with Ajax. For more information about Django interacting with Ajax, please pay attention to other related articles on this site!


Related articles: