The 2019 way of posting FILES to Django server using jQuery.

04 June 2019

Writing a script to uploading files have always been my most daunting task with Django 2.0 and Python 3. There's a few online resources, but they mostly use the autogenerated feature. I don't like that. I feel it's 2019, things should be more modern and dynamic by now.

This tutorial is not very newb friendly and requires some prior Python/Django and Javascript + jQuery knowledge... Copy and pasting won't work. It will work if you implement it correctly. You can easy customise it to your needs.

But after battling for a good 10 hours, I finally found a solution that works perfectly fine. No forms.

First things first - this method will upload your files to the /media folder of your Django project. So for that, add the following to your file.

MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

This will set your permissions as well as save your media file.

Now it's time for the HTML.

In my case, I used the Bulma css framework. They have a pretty cool looking upload button. I'm gonna go ahead and use that.

<div class="file is-boxed">
        <label class="file-label">
          <input id="profilePicUpload" class="file-input" type="file" >
          <span class="file-cta">
            <span class="file-icon">
              <i class="fas fa-upload"></i>
            <span class="file-label">
              Choose a profile picture

Also, I know I'm talking about 2019 and doing things progressively, but still sometimes a project doesn't require React, Vue or Angular - so for this, I'll be using jQuery.

Now open your javascript and add the following.

$('#profilePicUpload').on('change', function () {
    var file = this.files[0];
    var url = '/profilepicupload';

    var data = new FormData();
    data.append('file', file);

        type: "POST",
        enctype: 'multipart/form-data',
        url: url,
        data: data,
        processData: false,
        contentType: false,
        cache: false,
        timeout: 600000,
        success: function (data) {

            if (data.ok === true) {

            } else {

                alert('Upload failed');


        error: function (e) {
            alert('Upload failed');



In my case, there's no "submit" button or something - the file will upload immediately when you select it in your file selection dialog.

Now let's deal with the backend. In my file of the app, I add the following script:

from import FileSystemStorage
from django.conf import settings
import uuid

def ProfilePicUpload(request):
    details = get_object_or_404(UserData, user=request.user)

        if request.method == 'POST':
            #This is where it grabs your file from the Ajax POST.
            myfile = request.FILES['file']
            #Lets generate a UUID string to make sure all files remain unique named.
            id_1 = str(uuid.uuid1())
            # This is where we will save it.
            fs = FileSystemStorage(location='/media')

            # In order to rename, lets get the file extension.
            file_extension = os.path.splitext([1]
            newfilename = id_1 + file_extension
            # Cool, file renamed, now lets rename
            filename =, myfile)
            file_url = fs.url(filename)
            #This gets the directory / url of the saved file.


            #This saves the file directory in the database.

            details.profilepic = file_url

            return JsonResponse({"ok": True, "url": file_url, "filename":})

    except Exception as e:
        return JsonResponse({'ok': False})

Oh, the model field for this is a filefield and looks like this.

profilepic = models.FileField(null=True, blank=True)

Lastly, we need to update the URLS to the function. So in

   path('profilepicupload', views.ProfilePicUpload, name="upload"),

Also, this is assuming you're using Django 2.0 and above.

At last it works and I can upload stuff!

← Back to article list