Skip to content

Commit

Permalink
[#1384] Add custom to_native method to Base64ImageField
Browse files Browse the repository at this point in the history
Add Base64ImageField.to_native() to include the full path to the image
in any API use and add the option of requesting a thumbnail as part of an
API get request.

See docstring and comments in to_native() for more details.
  • Loading branch information
zzgvh committed Apr 7, 2015
1 parent 00a4d31 commit 6df929f
Showing 1 changed file with 43 additions and 6 deletions.
49 changes: 43 additions & 6 deletions akvo/rest/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import base64
import imghdr
import os
import six
import uuid

Expand All @@ -16,8 +15,7 @@

from rest_framework import serializers
from rest_framework.fields import ImageField

from akvo import settings
from sorl.thumbnail import get_thumbnail


class NonNullCharField(serializers.CharField):
Expand Down Expand Up @@ -69,10 +67,49 @@ def from_native(self, base64_data):
return super(Base64ImageField, self).from_native(data)

def to_native(self, value):
""" Return the full path to the image, including the MEDIA_URL part
"""
value = super(Base64ImageField, self).to_native(value)
return os.path.join(settings.MEDIA_URL, value)
:param value: A Base64ImageField object
:return: The full path to the image. If the request includes a special query string param a thumbnail is
generated and returned along with the original
If the querystring part of the request includes the query param "image_thumb_name" a thumbnail is generated,
provided that at least one of "width" and "height" parameters is also supplied. The image_thumb_name value is
used as the key for the thumbnail in the dict returned.
If a thumbnail is included a dict with two members is returned:
{
'original': '/full/path/to/original/image.png',
'<value of image_thumb_name QS param>': '/full/path/to/thumbnail/image.png'
}
This dict will be converted as appropriate to JSON or XML
NOTE: This special functionality works best when there is only one image field in a model. If there are more,
things will still work (I think), but all thumbs returned will have the same dimensions
"""
ORIGINAL_KEY = u'original'
if value:
# get the full path of original image
image_url = value.url
image_thumb_name = self.context['request'].GET.get('image_thumb_name')
# do we have a request for a thumbnail?
# also make sure the thumb isn't named "original"!
if image_thumb_name and image_thumb_name.lower() != ORIGINAL_KEY:
width = self.context['request'].GET.get('width')
height = self.context['request'].GET.get('height')
# set thumb size according to what data we got
if width and height:
thumb = get_thumbnail(value, '{}x{}'.format(width, height), quality=99)
elif width:
thumb = get_thumbnail(value, '{}'.format(width), quality=99)
elif height:
thumb = get_thumbnail(value, 'x{}'.format(height), quality=99)
else:
# bail if we get neither width nor heigth
return image_url
# populate dict with original and thumb paths
image_dict = {ORIGINAL_KEY: image_url}
image_dict[image_thumb_name] = thumb.url
return image_dict
return image_url

def get_file_extension(self, filename, decoded_file):
extension = imghdr.what(filename, decoded_file)
Expand Down

0 comments on commit 6df929f

Please sign in to comment.