How to send Django form with AJAX
Tags: django, python, javascript, webdev
Published: 2019-08-17 19:59:39

This post cross-published with [OnePublish](https://www.onepubli.sh)

What's up <b>DEV</b> Network?
<p>In this quick tutorial I am going to show you how to POST Django form without refreshing page using <b>AJAX</b>.</p>
<p>I am assuming that you already created your project. Let's start with creating our very simple Post model in <b>models.py</b></p>
```python
from django.db import models

class Post (models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField()

    def __str__(self):
        return self.title

```
<p>Once you created open <b>views.py</b> and insert following code:</p>
```python
from django.shortcuts import render
from django.http import JsonResponse
from .models import Post

def create_post(request):
    posts = Post.objects.all()
    response_data = {}

    if request.POST.get('action') == 'post':
        title = request.POST.get('title')
        description = request.POST.get('description')

        response_data['title'] = title
        response_data['description'] = description
      
        Post.objects.create(
            title = title,
            description = description,
            )
        return JsonResponse(response_data)

    return render(request, 'create_post.html', {'posts':posts})        
```
<p>As you see we imported <b>JsonResponse</b> which is an HttpResponse subclass that helps to create a JSON-encoded response. It is default Content-Type header is set to application/json. The first parameter, data, should be a dict instance. We will use JSON data to display created post right away. </p>  

<p>I highly recommend to take look following StackOverflow question  to have a better understanding difference between <b>request.POST[]</b> and <b> request.POST.get()</b></p>
{% stackoverflow 12518517 %}
<p> If you have more than one form in your page you can separate them by using <b>action</b>, so your view will not get multiple requests at the same time.</p>
<p>To create and save an object in a single step, we are using the <b>create()</b> method.</p>
<p>Let's take a look our html form now</p>

```html
<form method="POST" id="post-form">
  {% csrf_token %}
  <div class="form-group">
    <label>Title</label>
    <input type="text" class="form-control" id="title" placeholder="Title">
  </div>
   <div class="form-group">
     <label>Description</label>
     <textarea class="form-control" id="description" placeholder="Description"></textarea>
   </div>
   <button type="submit" class="btn btn-primary">Submit</button>
</form>
```
<p>As you know we are using csrf_token to make post request and it is a just simple bootstrap form. We give id for each input to get values with AJAX by id.</p>

```javascript
$(document).on('submit', '#post-form',function(e){
    $.ajax({
        type:'POST',
        url:'{% url "create" %}',
        data:{
            title:$('#title').val(),
            description:$('#description').val(),
            csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(),
            action: 'post'
        },
        success:function(json){
            document.getElementById("post-form").reset();
            $(".posts").prepend('<div class="col-md-6">'+
                '<div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">' +
                    '<div class="col p-4 d-flex flex-column position-static">' +
                        '<h3 class="mb-0">' + json.title + '</h3>' +
                        '<p class="mb-auto">' + json.description + '</p>' +
                    '</div>' +
                '</div>' +
            '</div>' 
            )
        },
        error : function(xhr,errmsg,err) {
        console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
    }
    });
});
```
<p>Note that you have to include jquery-2.2.4.min.js to your static files, you can take it from my <a href="https://github.com/raszidzie/django-form-with-ajax">git repository</a>.</p>
<p>Alright! What is going on here? Initially, it is important to add id property to your form, so jQuery can detect form submission. AJAX <b>type</b> specifies the type of request which is post because we are sending data to database and <b>url</b> specifies the URL to send the request to. Then, we are  using val() method to get the values of form elements by id and sending it with <b>data</b> parameter which specifies data to be sent to the server. It is necessary to get value of csrf_token otherwise it will cause 403 Forbidden error. As you see we specified action to let our view detect which form is submitting.</p>

<p>Once request successfully sent, we are cleaning form and appending our new post right away into the posts row.</p>
<blockquote>The .prepend() method inserts the specified content as the first child of each element in the jQuery collection (To insert it as the last child, use .append()).</blockquote>
<p>If some error occurs while sending request (I hope not😅) then the last function will add this error information to the console, so you can see what caused this nasty error. I guess you already know how to display error to user nicely.</p>
<p>At the end you will get following result</p>
<img src="https://thepracticaldev.s3.amazonaws.com/i/c1zafuarla7lhtg8a99g.gif" />

<h4>Mission Accomplished!</h4>
<p>You just learned how to POST Django form using AJAX 🚀🚀</p>
<p>You can clone or download this project from my <a href="https://github.com/raszidzie/django-form-with-ajax">git repository</a> and don't forget to follow and support me on <b>twitter</b> and <b>instagram</b>, join Reverse Astronauts community!👨‍🚀 See you next tutorial!</p> 
{% tag django %}