Tech Incent
Django

How to make pure javascript XmlHttpRequest or fetch request for get or post data in Django

how-to-make-pure-javascript-xmlhttprequest-fetch-in-django

Django application is ready dynamic. but with Ajax request, it will be more flexible and more dynamic. In some scenarios in Django application best to use the AJAX request.
There are a lot of developers who have confusion about ajax. let clear about ajax, Ajax stand for Asynchronous JavaScript And XML. Two ways we can make an Ajax request, One XMLHttpRequest on other hand Fetch. It can send and receive information in various formats, including JSON, XML, HTML, and text files. keep it in mind Jquery.ajax is actually make pure XMLHttpRequest. So don’t combine with ajax definition.

So I am going to give an example of pure javascript ajax(XMLHttpRequest, Fetch) with Django contact data.

Make Contact models

The best is to generate a contact app in Django. Create a Contact model with name, email, and message fields.

class Contact(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()
    message = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.email

Don’t forget to migrate

Create a Contact Form

Create forms.py in the contact app. and create ContactForm.

from django import forms

from .models import Contact

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        fields = '__all__'

Create a Django view

In contact app, views.py file adds contact_form and contact_list view function.

from django.shortcuts import render, redirect
from django.core import serializers
from django.http import JsonResponse

from .models import Contact
from .forms import ContactForm


def contact_form(request):
    form = ContactForm(request.POST or None)
    if form.is_valid():
        instance = form.save()
        if request.is_ajax():
            return JsonResponse({'success': True, 'data': serializers.serialize("json", [instance,])}, status=201)  # 201 = Created
        return redirect('contact_form')
    else:
        JsonResponse({'success': True}, status=422)  # 422 Unprocessable Entity
    return render(request, 'contact/contact_form.html', {'form': form})



def contact_list(request):
    obj_list = serializers.serialize("json", Contact.objects.all())
    return JsonResponse({'contact_list': obj_list, 'success': True}, status=200)  # 200 = Ok

contact_form: contact_form view a Django simple contact form view for response Django template. we make an XMLHttpRequest ajax ‘post’ method request to this view

contact_list: contact_list view is a Django view to response JSON data with contact_list. We make Fetch with ‘get’ method request

Make sure JsonResponse method import, ajax response, will be Django JsonResponse

Add contact_form URL in Django

add urls.py file in contact app directory.

from django.urls import path

from .views import contact_form, contact_list

urlpatterns = [
    path('contact', contact_form, name='contact_form'),
    path('contact-list', contact_list, name='contact_list)
]

Great we are completed the back-end Django ajax setting, next make front end ajax request with XMLHttpRequest

Create Contact_form.html file for contact_form view

Crate contact_form.html in the templates directory,  ‘contact/contact_form.html file’

{% extends 'base.html' %}

{% block content %}
<div class="container mt-5">
    <div class="card">
        <div class="card-body">
            <form id="contact_form" action="{% url 'contact_form' %}" method="post">
                {% csrf_token %}
                {% for error in form.non_field_errors %}
                <div class="alert alert-danger" role="alert"> {{ error }}</div>
                {% endfor %}
                {{ form.as_p }}
                <button type="submit">Submit</button>
            </form>
        </div>
    </div>
</div>

<div class="container mt-4 mb-5">
    <div class="card">
        <div class="card-body">
            <table id="contact_list_table" class="table">
                <thead>
                  <tr>
                    <th scope="col">#</th>
                    <th scope="col">Name</th>
                    <th scope="col">Email</th>
                    <th scope="col">Message</th>
                  </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
    </div>
</div>
{% endblock %}

{% block js %}
<script>
  let contactTable = document.getElementById('contact_list_table');

  /* -------------- Contact form Submit ------------------ */ 
  let contactForm = document.getElementById('contact_form')
  contactForm.addEventListener('submit', function(e) {
    e.preventDefault();
    let thisForm = e.target
    const method = thisForm.getAttribute('method');
    const endpoint = thisForm.getAttribute('action');
    let data = new FormData(thisForm);
    let xhr = new XMLHttpRequest();
    xhr.open('post', endpoint, true);
    // const csrftoken = getCookie('csrftoken');
    // xhr.setRequestHeader("X-CSRFToken", csrftoken);
    xhr.setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest')
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
    xhr.responseText = 'json'
    xhr.onload = () => {
      const res = JSON.parse(xhr.response)
      let {success, data} = res
      if(success){
        let {name, email, message} = JSON.parse(data)[0].fields
        let itemTr = `<tr>
                    <th scope="row">${parseInt(contactTable.children[1].lastChild.firstElementChild.innerText) + 1}</th>
                    <td>${name}</td>
                    <td>${email}</td>
                    <td>${message}</td>
                  </tr>`
        contactTable.children[1].insertAdjacentHTML('beforeend', itemTr)
      }
    }
    xhr.onerror = () => {
      console.log(xhr.error)
    }
    xhr.send(data)
  })

  /* ------------------ Fetach contact form data with async ---------------- */
  let endpoint = "{% url 'contact_list' %}"
  async function loadContact() {
    let contactTrItems = ``
    try{
      let response = await fetch(endpoint, {
          method: 'get'
      });
      // the server responds with contact list
      if (response.ok){
          let {contact_list, success} = await response.json();
          contact_list = JSON.parse(contact_list)  // make string to json
          // console.log(contact_list.length, success)
          // console.dir(contact_list)
          if(contact_list.length > 0) {
              contact_list.map(({fields: {name, email, message}}, index) => {
                  // console.log(name, email, message)
                  let itemTr = `<tr>
                  <th scope="row">${index + 1}</th>
                  <td>${name}</td>
                  <td>${email}</td>
                  <td>${message}</td>
                </tr>`
                contactTrItems += itemTr
              })
          }
        contactTable.children[1].innerHTML = contactTrItems
      } else{
          console.log('not okay', response)
      }
    } catch(err){
      console.log(err)
    }
  }

  document.addEventListener('DOMContentLoaded', function(){
      loadContact()
  })

</script>
{% endblock %}

contact_form submitted with XMLHttpRequest request with post method. and Fetching contact list data with fetch ajax request with ‘get’ method.

Related posts

How to create Django form?

Sajal Mia

Explained Django inline formset factory with example?

Sajal Mia

How to render Django form individual fields manually?

Sajal Mia

How to optimize your Django application for more speed with ORM?

Sajal Mia

Django Send Email with AWS Simple Email Service(SES)

Sajal Mia

How to deploy django and react in heroku ?

Tech Incent