gault-millau/apps/gallery/serializers.py
2019-11-22 13:02:04 +03:00

86 lines
3.1 KiB
Python

from django.conf import settings
from django.core.validators import MinValueValidator, MaxValueValidator
from rest_framework import serializers
from sorl.thumbnail.parsers import parse_crop
from sorl.thumbnail.parsers import ThumbnailParseError
from . import models
class ImageSerializer(serializers.ModelSerializer):
"""Serializer for model Image."""
# REQUEST
file = serializers.ImageField(source='image',
write_only=True)
width = serializers.IntegerField(write_only=True, required=False)
height = serializers.IntegerField(write_only=True, required=False)
margin = serializers.CharField(write_only=True, allow_null=True,
required=False,
default='center')
quality = serializers.IntegerField(write_only=True, allow_null=True, required=False,
default=settings.THUMBNAIL_QUALITY,
validators=[
MinValueValidator(1),
MaxValueValidator(100)])
# RESPONSE
url = serializers.ImageField(source='image',
read_only=True)
cropped_image = serializers.DictField(read_only=True, allow_null=True)
orientation_display = serializers.CharField(source='get_orientation_display',
read_only=True)
class Meta:
"""Meta class"""
model = models.Image
fields = [
'id',
'file',
'url',
'orientation',
'orientation_display',
'title',
'width',
'height',
'margin',
'quality',
'cropped_image',
]
extra_kwargs = {
'orientation': {'write_only': True}
}
def validate(self, attrs):
"""Overridden validate method."""
image = attrs.get('image').image
crop_width = attrs.get('width')
crop_height = attrs.get('height')
margin = attrs.get('margin')
if crop_height and crop_width and margin:
xy_image = (image.width, image.width)
xy_window = (crop_width, crop_height)
try:
parse_crop(margin, xy_image, xy_window)
except ThumbnailParseError:
raise serializers.ValidationError({'margin': 'Unrecognized crop option: %s' % margin})
return attrs
def create(self, validated_data):
"""Overridden create method."""
width = validated_data.pop('width', None)
height = validated_data.pop('height', None)
quality = validated_data.pop('quality')
margin = validated_data.pop('margin')
instance = super().create(validated_data)
if instance and width and height:
setattr(instance,
'cropped_image',
instance.get_cropped_image(
geometry=f'{width}x{height}',
quality=quality,
margin=margin))
return instance