Adding drag and drop image uploads to your Django site in 5 minutes with DropzoneJS
I've been using the Django admin to upload images to my site one-by-one for a few weeks now and I've finally decided I've had enough of it and started looking for a Javascript library that will enable me to do bulk uploads.
I still have around 100 or so albums and at least 1,000 more pictures to upload so you can just imagine how tedious that would be. I found this library called DropzoneJS that turned out to be really easy to implement that I now feel silly having waited this long.
While it's very customizable, I just used the default settings and it worked well enough for me. The implementation code is tiny.
Here's how I have mine setup.
Model
I have 2 models for my Gallery app, an Album model and a Photo model with a Foreign Key to Album.
# gallery/models.py
class Album(TimeStampedModel):
title = models.CharField(max_length=250)
description = models.TextField(blank=True, null=True)
cover_photo = models.ForeignKey('Photo', related_name='+', blank=True,
null=True)
is_public = models.BooleanField(default=True)
date_added = models.DateField(null=True, blank=True)
tags = TaggableManager(blank=True, help_text=None)
order = models.PositiveIntegerField(default=9999)
class Photo(TimeStampedModel):
album = models.ForeignKey(Album)
file = models.ImageField(upload_to=upload_to)
description = models.TextField(blank=True, null=True)
is_public = models.BooleanField(default=True)
tags = TaggableManager(blank=True, help_text=None)
View
I created an AJAX view where the POST request from DropzoneJS will be sent to. Note that I'm using the django-braces package here.
# gallery/views.py
from django.views.generic import View
from braces.views import (
AjaxResponseMixin,
JSONResponseMixin,
LoginRequiredMixin,
SuperuserRequiredMixin,
)
from calazanblog.gallery.models import Album, Photo
AjaxPhotoUploadView(LoginRequiredMixin,
SuperuserRequiredMixin,
JSONResponseMixin,
AjaxResponseMixin,
View):
"""
View for uploading photos via AJAX.
"""
def post_ajax(self, request, *args, **kwargs):
try:
album = Album.objects.get(pk=kwargs.get('pk'))
except Album.DoesNotExist:
error_dict = {'message': 'Album not found.'}
return self.render_json_response(error_dict, status=404)
uploaded_file = request.FILES['file']
Photo.objects.create(album=album, file=uploaded_file)
response_dict = {
'message': 'File uploaded successfully!',
}
return self.render_json_response(response_dict, status=200)
URL
# gallery/urls.py
from django.conf.urls import patterns, url
from calazanblog.gallery import views
urlpatterns = patterns('',
url(
regex=r'^(?P<pk>\d+)/ajax-upload/$,
view=views.AjaxPhotoUploadView.as_view(),
name='ajax_photo_upload_view',
),
)
Template
<!-- templates/gallery/photo_list.html -->
<!-- Upload Photos -->
{% if user.is_superuser %}
<form id="add-photos" action="{% url 'ajax_photo_upload_view' album.id %}" class="dropzone">
{% csrf_token %}
</form>
{% endif %}
And here's what it looks like:
That's it! You don't even need to write any Javascript unless you need to customize it.
Tags: javascript, howto, tech, software development, django