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.

