Django Image And File Upload Using Ajax

Django Image And File Upload Using Ajax

Let's learn about how to work with Django image and file upload using Ajax. In most of the cases I personally use django file or image uploads using ajax. If we use normal upload then browser will reload the page in order to load the requested response and we will not have the files in the file fields due to page refreshed by the browser, again user has to browse the files if any error occurs while validating the form. If we use the ajax upload then the control is taken by the javascript. So, the page will not be refreshed and we will have the files in the fields selected by the user. If we use normal upload then browser will also send request to get the static resources so, It will have an effect on the page speed. Django image and file upload using Ajax will only requests for form validation so, other resources like static(css/js/images) will not be requested.

Lets see the code of Django image and file upload using Ajax

models.py

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
    photo = models.ImageField(upload_to="images")
    attachment = models.FileField(upload_to="attachments")
    phone = models.CharField(max_length=10)

forms.py

from django import forms
from .models import Profile


class ImageFileUploadForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ('phone', 'photo', 'attachment',) 

views.py

from django.shortcuts import render
from django.http import JsonResponse
from .forms import ImageFileUploadForm

def django_image_and_file_upload_ajax(request):
    if request.method == 'POST':
       form = ImageFileUploadForm(request.POST, request.FILES)
       if form.is_valid():
           form.save()
           return JsonResponse({'error': False, 'message': 'Uploaded Successfully'})
       else:
           return JsonResponse({'error': True, 'errors': form.errors})
    else:
        form = ImageFileUploadForm()
        return render(request, 'django_image_upload_ajax.html', {'form': form})

django_image_upload_ajax.html

<html>
  <head>
     <title> Django image and file upload using ajax </title>
  </head>
<body>
   <form 
    enctype="multipart/form-data"
    id="id_ajax_upload_form" method="POST"
    novalidate="">
      { % csrf_token %}
      { { form.as_p }}
      <input type="submit" />
   </form>
   <script 
   src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
   <script type="text/javascript">
    // form upload
    $('#id_ajax_upload_form').submit(function(e){
        e.preventDefault();
        $form = $(this)
        var formData = new FormData(this);
        $.ajax({
            url: window.location.pathname,
            type: 'POST',
            data: formData,
            success: function (response) {
                $('.error').remove();
                console.log(response)
                if(response.error){
                    $.each(response.errors, function(name, error){
                        error = '<small class="text-muted error">' + error + '</small>'
                        $form.find('[name=' + name + ']').after(error);
                    })
                }
                else{
                    alert(response.message)
                    window.location = ""
                }
            },
            cache: false,
            contentType: false,
            processData: false
        });
    });
    // end
   </script>
</body>
</html>

Points to be noted when using Django image and file upload using Ajax

  • In template we must define enctype="multipart/form-data"otherwise user browsed files (in our case image and attachment) will not sent in the request. So, Django will return errors like "This filed is required".

  • In views.py return only JsonResponse. Do not return HttpResponse. By default in HttpResponse content_type is set to "html/text" where as in JsonResponse the content_type is set to "json/application". When content type is set to "json" then the ajax will convert the response body into JSON data. Otherwise we have to manually parse response body to json using "JSON.parse"

  • We must define STATIC settings and MEDIA settings in settings.py file if these are not configured properly then we may get errors.