How can I thumbnail images in serialization of Django REST Framework? - django

I recently jumped into Django REST Framework. Before using it, I thumbnailed images using django-imagekit. Like you see the models below, it worked well, so I used original size images from image and thumbnailed size images from image_thumbnail.
models.py
class Image(models.Model):
...
image = ProcessedImageField(null=True, blank=True, upload_to=image_path,
processors=[Thumbnail(1000, 1400)], format='JPEG')
image_thumbnail = ImageSpecField(
source='image', format='JPEG', options={'quality': 40})
...
The problem is I can't use image_thumbnail in my serializers. I can use image, but image_thumbnail throws an error message A server error occurred. Please contact the administrator.
serializers.py
class ImageRandomSerializer(ModelSerializer):
class Meta:
model = Image
fields = ('image', 'image_thumbnail', )
Can I not thumbnailed images from models.py in serializers.py? Should I thumbnail them with some Django REST Framework thumbnail tool?
UPDATE
After setting DEBUG=True, it throws the error 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte.

I just found the answer from here.
Added image_thumbnail = ImageField(read_only=True), and now it's working well.
from rest_framework.serializers import ImageField
class ImageRandomSerializer(ModelSerializer):
store = StoreDomainKeySerializer()
image_thumbnail = ImageField(read_only=True)
class Meta:
model = Image
fields = ('store', 'image', 'image_thumbnail',)

Related

in django set default image to ImageField as Default object

I have a model in the model and Imagefield is there.
class Job(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to=" jobOpeningImages", default=' jobOpeningImages/1_oKH7Co9.jpeg', blank=True)
But I am not getting any current image URL in the localhost.
I am expecting this type of result
So how can we achieve the below? in first image
Currently: jobOpeningImages/1_oKH7Co9.jpeg

Django Rest Framework: The 'image' attribute has no file associated with it

I'm using Django Rest Framework to create REST endpoints for a frontend.
I have a model where there is the possibility of uploading 3 images (foto_1, foto_2, foto_3).
class Ocorrencia(TimeStampedModel):
(...)
foto_1 = models.ImageField("Foto 1", upload_to="ocorrencias/", blank=True)
foto_2 = models.ImageField("Foto 2", upload_to="ocorrencias/", blank=True)
foto_3 = models.ImageField("Foto 3", upload_to="ocorrencias/", blank=True)
My serializer is the following:
class OcorrenciaSerializer(GeoFeatureModelSerializer):
(...)
foto_1 = serializers.ImageField(allow_empty_file=True, allow_null=True, required=False, use_url=True)
foto_2 = serializers.ImageField(allow_empty_file=True, allow_null=True, required=False, use_url=True)
foto_3 = serializers.ImageField(allow_empty_file=True, allow_null=True, required=False, use_url=True)
class Meta:
model = models.Ocorrencia
geo_field = 'geometria'
fields = ('foto_1', 'foto_2', 'foto_3')
If for example foto_3 has no file url associated in the database (it's saved as empty string when it's empty) then I get the following error when retrieving the associated endpoint:
Exception Value: The 'foto_3' attribute has no file associated with it.
Using allow_empty_file=True, allow_null=True, required=False when defining the serializer for the image fields seems to not do anything.
UPDATE 1
I found that this is related to using GeoFeatureModelSerializer, this is part of Django Rest Framework GIS. I'll have to seek a solution on that route. If I happen to use the default serializer class of DRF I have no issues. I was almost going insane with this issue. If I find a solution using GeoFeatureModelSerializer I'll post it here.
UPDATE 2
Updated Django-Rest-Framework-Gis to latest version and fixed it. Thank you all for your comments and suggestions.

Django Model store image file size

I am using Django 1.6. I have a model for uploading image files that looks like this.
class Image(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
url = models.ImageField(upload_to=get_image_path,
null=True,
blank=True,
height_field = 'height',
width_field = 'width',
verbose_name='Image')
height = models.IntegerField(blank=True)
width = models.IntegerField(blank=True)
size = models.IntegerField(blank=True)
format = models.CharField(max_length=50)
caption = models.CharField(max_length=255)
def clean(self):
self.size = self.url.size
class Meta:
db_table = 'image'
As you can see, I am storing the size of the image when the clean() method is called. This works for what I want to do, but is this best practise? Is there a better way to automatically save the image's file size when saving?
The second part of my question is how can I get the content type as well?
Thanks,
Mark
Model.clean() should be used for validation - do not use it to update/save the data, but rather use it to correct any invalid data (or throw an exception/error message).
You may want to consider not even storing the size of the image in the database, given that you can access it from the ImageField - it eliminates the possibility of the data becoming inconsistent as it changes over time.
I believe this question/answer should address your second question.
For the first question
Check out the Python Imaging Library PIL on this thread.
from PIL import Image
im=Image.open(filepath)
im.size # (width,height) tuple
For the second question
HttpRequest.META, more specifically HttpRequest.META.get('CONTENT_TYPE')
from this thread

Default Image in Django Rest Framework

I have an optional ImageField in my model with a default image. I am using Django Rest Framework for the model api. However when I try to post (post request outside the browser) without images I continue getting the error:No file was submitted. Check the encoding type on the form.
models.py
class Detector(models.Model):
average_image = models.ImageField(upload_to='average_image/',
default='average_image/default.png',
null=True, blank=True)
serializer.py
class DetectorSerializer(serializers.ModelSerializer):
class Meta:
model = Detector
fields = ('average_image')
views.py
class DetectorAPIList(generics.ListCreateAPIView):
serializer_class = DetectorSerializer
What am I missing?
Thanks for your time!
i hit the same issue, i had to explicitly mark my image field in the serializer as blank:
class DetectorSerializer(serializers.ModelSerializer):
average_image = serializers.ImageField(source='average_image', blank=True)
class Meta:
model = Detector
fields = ('average_image',)
It seems that rest framework is unable to grab it from model or something. After this i am able to POST data to the API using requests like this:
import requests
from requests.auth import HTTPBasicAuth
r = requests.post(
'http://localhost:8000/detectors/',
data={'some': 'data'},
auth=HTTPBasicAuth('user', 'password')
)
print r.text
And this is the response, as you can see it used the default from the model field definition:
{"average_image": "average_image/default.png"}
You can also try to POST with specified file:
r = requests.post(
'http://localhost:8000/detectors/',
files={'average_image': open('/path/to/image.jpg')},
data={'some': 'data'},
auth=HTTPBasicAuth('user', 'password')
)
print r.text
Hope this helps.

Resize and Rename Image in Django UpdateView

I want to be able to create 3 different sizes of an image when a user uploads an image in an UpdateView in Django.
I also want to be able to rename the file they upload to something like username_thumb_01.jpg, username_original_01.jpg, username_medium_01.jpg.
views.py
class UserProfileEditView(UpdateView):
model = UserProfile
form_class = UserProfileForm
template_name = "edit_profile.html"
forms.py
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
website = models.URLField(null=True, blank=True)
avatar = models.ImageField(upload_to="user-photos", null=True, blank=True)
I tried to add something like the following to my UserProfileEditView but it didnt work and I wasnt sure If i was on the right track.
def form_valid(self, form):
if self.request.files:
filename= join(settings.MEDIA_ROOT, profile.avatar.name)
im = Image.open(filename)
im.thumbnail((160,160), Image.ANTIALIAS)
im.save(imfn, "JPEG")
form.save
Has anyone done this before? How can I accomplish it ?
Although their approach is different I suggest using sorl-thumbnail. Instead of creating the images when they are uploaded what this does is creates them when they are required and then caches them using whatever caching system you specify.
I do this by using a custom image field. The code for it is available on github at https://github.com/hellsgate1001/django-thumbs.
I didn't create this, I forked it to add a bit more flexibility to the thumbnail creation and also to ensure it works with Django 1.5