Login

ImageField for Google App Engine

Author:
davepeck
Posted:
November 17, 2009
Language:
Python
Version:
1.1
Score:
3 (after 3 ratings)

This is a replacement for Django's built-in ImageField. It uses the Google AppEngine image APIs in order to validate.

Notes:

  1. Validation of the field counts against your App Engine transformations quota.
  2. This code assumes you're only using the in-memory file upload handler. None of the other stock handlers work well on App Engine; you should probably disable them.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from django import forms
from django.utils.translation import ugettext_lazy as _
from google.appengine.api import images

# Django's built-in ImageField doesn't work on AppEngine because
# it relies on unavailable PIL APIs. Here's my own version that works.

def image_bytes_are_valid(image_bytes):
    try:
        test_image = images.Image(image_bytes)
        # Unfortunately the only way to validate image bytes on AppEngine is to
        # perform a transform. Lame.
        ignored_output = test_image.execute_transforms(images.PNG)
    except images.Error:
        return False
    return True

class AppEngineImageField(forms.FileField):
    default_error_messages = {
        'invalid_image': _(u"Upload a valid image. The file you uploaded was either not an image or was a corrupted image."),
    }
    
    def clean(self, data, initial=None):
        raw_file = super(AppEngineImageField, self).clean(data, initial)
        if raw_file is None:
            return None
        elif not data and initial:
            return initial
            
        if hasattr(data, 'read'):
            bytes = data.read()
        else:
            try:
                bytes = data['content']
            except:
                bytes = None
        
        if bytes is None:
            raise forms.ValidationError(self.error_messages['invalid_image'])
        
        if (len(bytes) > 0) and (not image_bytes_are_valid(bytes)):
            raise forms.ValidationError(self.error_messages['invalid_image'])
        
        if hasattr(raw_file, 'seek') and callable(raw_file.seek):
            raw_file.seek(0)
            
        return raw_file
        
                
                

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

johnecon (on July 8, 2012):

hello dave! I would like to use this snippet which seems exactly what i need. So under Event/models.py i have something like this

class Event(models.Model): title = models.CharField(max_length=200) address = models.CharField(max_length=200) image = AppEngineImageField()

and under Event/admin.py I have the following class

class EventAdmin(admin.ModelAdmin): list_display = ('address', 'image', 'category', 'description', 'title', 'activationDate', 'expiryDate', 'isExpired') search_fields = ['title']

admin.site.register(Event, EventAdmin)

But when i go to admin area to add a new event unfortunately i am not able to upload an image to my event.. Any suggestions??

#

Please login first before commenting.