Browse By

Django – Integrating zmathew/django-ajax-upload-widget with Amazon S3 bucket

Django - Support for Amazon S3 bucket with zmathew/django-ajax-upload-widget

Few days ago I have used django-ajax-upload-widget for ajax upload on my local system and it works perfectly but when I used that with Amazon S3 for static files it didn’t work properly.

I have used,


When I used Amazon S3, I faced following issues:

  1. It didn’t show me any preview when I select image.

Support for Amazon S3 Amazone server with zmathew/django-ajax-upload-widget

2. After this, when I clicked on submit it return following error.

Support for Amazon S3 Amazon server with zmathew/django-ajax-upload-widget

AjaxUploadException Error

Django – Integrating zmathew/django-ajax-upload-widget with Amazon S3 bucket

After that I have gone through StackOverFlow and other Django related sites for the solutions. After trying different  Solutions, I figure out proper solution and wanted to share with you.

First of all download zmathew/django-ajax-upload-widget library.

To support Amazon S3 to django-ajax-upload-widget, you have to replace ajax_upload/ files with this code.

from django import forms 
from django.conf import settings 
from django.core.files import File 
from django.core.urlresolvers import reverse 
from django.utils.safestring import mark_safe 
from django.utils.translation import ugettext as _ 

import urllib2 
import urlparse 

from ajax_upload.models import UploadedFile 

class AjaxUploadException(Exception): 

class AjaxClearableFileInput(forms.ClearableFileInput): 
    template_with_clear = ''  # We don't need this 
    template_with_initial = '%(input)s' 

    def render(self, name, value, attrs=None): 
        attrs = attrs or {} 
        if value: 
            filename = u'%s%s' % (settings.MEDIA_URL, value) 
            filename = '' 
            'class': attrs.get('class', '') + 'ajax-upload', 
            'data-filename': filename,  # This is so the javascript can get the actual value 
            'data-required': self.is_required or '', 
            'data-upload-url': reverse('ajax-upload') 
        output = super(AjaxClearableFileInput, self).render(name, value, attrs) 
        return mark_safe(output) 

    def value_from_datadict(self, data, files, name): 
        # If a file was uploaded or the clear checkbox was checked, use that. 
        file = super(AjaxClearableFileInput, self).value_from_datadict(data, files, name) 
        if file is not None:  # super class may return a file object, False, or None 
            return file  # Default behaviour 
        elif name in data:  # This means a file path was specified in the POST field 
            file_path = data.get(name) 
            if not file_path: 
                return False  # False means clear the existing file 

            parsed_file_url = urlparse.urlparse(file_path) 
            parsed_media_url = urlparse.urlparse(settings.MEDIA_URL) 
            if parsed_file_url.hostname == parsed_media_url.hostname: 
                # Strip and media url to determine the path relative to media url base 
                relative_path = parsed_file_url.path[len(parsed_media_url.path):] 
                relative_path = urllib2.unquote(relative_path.encode('utf8')).decode('utf8') 
                    uploaded_file = UploadedFile.objects.get(file=relative_path) 
                except UploadedFile.DoesNotExist: 
                    # Leave the file unchanged (it could be the original file path) 
                    return None 
                    return File(uploaded_file.file) 
                raise AjaxUploadException(u'%s %s' % (_('File path not allowed:'), file_path)) 
        return None


After above changes django-ajax-upload-widget works perfectly Amazon S3. I hope this solution will help you.