2013-09-22

How to Create a File Upload Widget

Ajaxified file uploads are becoming de facto standard on the web. People want to see what they chose right after selecting a file instead of during submit of the form. Also if a form has validation errors, nobody wants to select the files again; the selection made should be still available in the form. Therefore, we need a solution that works by Ajax.

Luckily there is a Django app that can help. It's called django-ajax-uploader. Ajax uploader allows to create asynchronous single and multiple file uploads. All uploads are done into the uploads directory. In addition to the default functionality we need a possibility to show the preview of the temporary uploaded file, translate all messages and buttons, delete a file, move a file to a specific directory. I created a demo project which implements all that.

If you have a ModelForm with a FileField or ImageField, you need to not show this field in the form, but instead to add a hidden field for uploaded file path. When you choose a file, it will be uploaded to a temporary uploads directory and its path will be set in the hidden field. Also you need a hidden BooleanField for the state of file deletion. When you submit the form, the file will be moved from the temporary location to the correct location defined by the FileField or ImageField.

In the given example, besides django-ajax-uploader, I am using django-crispy-forms with bootstrap 3.0.0 support. It allows you to define the structure for the forms without creating repetitive HTML markup.

This would be a quick workflow of integrating ajax uploads into your project:

  • Install django-ajax-uploader and django-crispy-forms.
  • Put 'crispy_forms' and 'ajaxuploader' into INSTALLED_APPS.
  • Define CRISPY_TEMPLATE_PACK = 'bootstrap3' in the settings.
  • Define the url rule for ajax uploader
    from ajaxuploader.views import AjaxFileUploader
    uploader = AjaxFileUploader()
    urlpatterns = patterns('',
        # ...
        url(r'^helper/ajax-upload/$', uploader, name="ajax_uploader"),
        # ...
    )
    
  • Create a form for your model which will have the ajax uploader.
  • Create the view which will handle your model and the chosen files and call it in your urls.
  • Create the template with appropriate javascript.

For a working example, please check image uploads project.

No comments:

Post a Comment