refactored upload image endpoint
This commit is contained in:
parent
00d7bbe7ec
commit
f7703f18b0
|
|
@ -1,4 +1,8 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from sorl.thumbnail.parsers import parse_crop
|
||||||
|
from sorl.thumbnail.parsers import ThumbnailParseError
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|
@ -8,10 +12,21 @@ class ImageSerializer(serializers.ModelSerializer):
|
||||||
# REQUEST
|
# REQUEST
|
||||||
file = serializers.ImageField(source='image',
|
file = serializers.ImageField(source='image',
|
||||||
write_only=True)
|
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
|
# RESPONSE
|
||||||
url = serializers.ImageField(source='image',
|
url = serializers.ImageField(source='image',
|
||||||
read_only=True)
|
read_only=True)
|
||||||
|
cropped_image = serializers.DictField(read_only=True, allow_null=True)
|
||||||
orientation_display = serializers.CharField(source='get_orientation_display',
|
orientation_display = serializers.CharField(source='get_orientation_display',
|
||||||
read_only=True)
|
read_only=True)
|
||||||
|
|
||||||
|
|
@ -25,7 +40,46 @@ class ImageSerializer(serializers.ModelSerializer):
|
||||||
'orientation',
|
'orientation',
|
||||||
'orientation_display',
|
'orientation_display',
|
||||||
'title',
|
'title',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'margin',
|
||||||
|
'quality',
|
||||||
|
'cropped_image',
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'orientation': {'write_only': True}
|
'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
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,18 @@ class SORLImageMixin(models.Model):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_cropped_image(self, geometry: str, quality: int, margin: str) -> dict:
|
||||||
|
cropped_image = get_thumbnail(self.image,
|
||||||
|
geometry_string=geometry,
|
||||||
|
crop=margin,
|
||||||
|
quality=quality)
|
||||||
|
return {
|
||||||
|
'geometry_string': geometry,
|
||||||
|
'crop_url': cropped_image.url,
|
||||||
|
'quality': quality,
|
||||||
|
'margin': margin
|
||||||
|
}
|
||||||
|
|
||||||
image_tag.short_description = _('Image')
|
image_tag.short_description = _('Image')
|
||||||
image_tag.allow_tags = True
|
image_tag.allow_tags = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -399,6 +399,13 @@ SORL_THUMBNAIL_ALIASES = {
|
||||||
'establishment_xlarge': {'geometry_string': '640x360', 'crop': 'center'},
|
'establishment_xlarge': {'geometry_string': '640x360', 'crop': 'center'},
|
||||||
'establishment_detail': {'geometry_string': '2048x1152', 'crop': 'center'},
|
'establishment_detail': {'geometry_string': '2048x1152', 'crop': 'center'},
|
||||||
'establishment_original': {'geometry_string': '1920x1080', 'crop': 'center'},
|
'establishment_original': {'geometry_string': '1920x1080', 'crop': 'center'},
|
||||||
|
'city_xsmall': {'geometry_string': '70x70', 'crop': 'center'},
|
||||||
|
'city_small': {'geometry_string': '140x140', 'crop': 'center'},
|
||||||
|
'city_medium': {'geometry_string': '280x280', 'crop': 'center'},
|
||||||
|
'city_large': {'geometry_string': '280x280', 'crop': 'center'},
|
||||||
|
'city_xlarge': {'geometry_string': '560x560', 'crop': 'center'},
|
||||||
|
'city_detail': {'geometry_string': '1120x1120', 'crop': 'center'},
|
||||||
|
'city_original': {'geometry_string': '2048x1536', 'crop': 'center'},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user