"""Location app common serializers.""" from django.contrib.gis.geos import Point from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from location import models from utils.serializers import TranslatedField from gallery.models import Image class CountrySerializer(serializers.ModelSerializer): """Country serializer.""" name_translated = TranslatedField() class Meta: model = models.Country fields = [ 'id', 'code', 'svg_image', 'name_translated', ] class CountrySimpleSerializer(serializers.ModelSerializer): """Simple country serializer.""" name_translated = TranslatedField() class Meta: """Meta class.""" model = models.Country fields = ('id', 'code', 'name_translated') class RegionSerializer(serializers.ModelSerializer): """Region serializer""" country = CountrySerializer(read_only=True) country_id = serializers.PrimaryKeyRelatedField( source='country', queryset=models.Country.objects.all(), write_only=True ) class Meta: model = models.Region fields = [ 'id', 'name', 'code', 'parent_region', 'country', 'country_id' ] class CityShortSerializer(serializers.ModelSerializer): """Short city serializer""" country = CountrySerializer(read_only=True) class Meta: """Meta class""" model = models.City fields = ( 'id', 'name', 'code', 'country', ) class CropImageSerializer(serializers.Serializer): """Serializer for crop images for City object.""" xsmall_url = serializers.SerializerMethodField() small_url = serializers.SerializerMethodField() medium_url = serializers.SerializerMethodField() large_url = serializers.SerializerMethodField() xlarge_url = serializers.SerializerMethodField() detail_url = serializers.SerializerMethodField() def get_xsmall_url(self, obj): """Get crop preview.""" return obj.instance.get_image_url('location_city_xsmall') def get_small_url(self, obj): """Get crop preview.""" return obj.instance.get_image_url('location_city_small') def get_medium_url(self, obj): """Get crop preview.""" return obj.instance.get_image_url('location_city_medium') def get_large_url(self, obj): """Get crop preview.""" return obj.instance.get_image_url('location_city_large') def get_xlarge_url(self, obj): """Get crop preview.""" return obj.instance.get_image_url('location_city_xlarge') def get_detail_url(self, obj): """Get crop preview.""" return obj.instance.get_image_url('location_city_detail') class CityImageSerializer(serializers.ModelSerializer): """Serializer for returning crop images of news image.""" orientation_display = serializers.CharField(source='get_orientation_display', read_only=True) original_url = serializers.URLField(source='image.url') auto_crop_images = CropImageSerializer(source='image', allow_null=True) class Meta: model = Image fields = [ 'id', 'title', 'orientation_display', 'original_url', 'auto_crop_images', ] extra_kwargs = { 'orientation': {'write_only': True} } class CityGallerySerializer(serializers.ModelSerializer): """Serializer class for model NewsGallery.""" class Meta: """Meta class""" model = models.CityGallery fields = [ 'id', 'is_main', ] def get_request_kwargs(self): """Get url kwargs from request.""" return self.context.get('request').parser_context.get('kwargs') def validate(self, attrs): """Override validate method.""" news_pk = self.get_request_kwargs().get('pk') image_id = self.get_request_kwargs().get('image_id') news_qs = models.City.objects.filter(pk=news_pk) image_qs = Image.objects.filter(id=image_id) if not news_qs.exists(): raise serializers.ValidationError({'detail': _('News not found')}) if not image_qs.exists(): raise serializers.ValidationError({'detail': _('Image not found')}) news = news_qs.first() image = image_qs.first() attrs['news'] = news attrs['image'] = image return attrs class CitySerializer(serializers.ModelSerializer): """City serializer.""" region = RegionSerializer(read_only=True) region_id = serializers.PrimaryKeyRelatedField( source='region', queryset=models.Region.objects.all(), write_only=True ) country_id = serializers.PrimaryKeyRelatedField( source='country', queryset=models.Country.objects.all(), write_only=True ) city_gallery = CityGallerySerializer(many=True, read_only=True) country = CountrySerializer(read_only=True) class Meta: model = models.City fields = [ 'id', 'name', 'code', 'region', 'region_id', 'country_id', 'postal_code', 'is_island', 'city_gallery', 'country' ] class AddressBaseSerializer(serializers.ModelSerializer): """Serializer for address obj in related objects.""" latitude = serializers.FloatField(allow_null=True) longitude = serializers.FloatField(allow_null=True) # todo: remove this fields (backward compatibility) geo_lon = serializers.FloatField(source='longitude', allow_null=True, read_only=True) geo_lat = serializers.FloatField(source='latitude', allow_null=True, read_only=True) class Meta: """Meta class.""" model = models.Address fields = ( 'id', 'street_name_1', 'street_name_2', 'number', 'postal_code', 'latitude', 'longitude', # todo: remove this fields (backward compatibility) 'geo_lon', 'geo_lat', ) def validate_latitude(self, value): if -90 <= value <= 90: return value raise serializers.ValidationError(_('Invalid value')) def validate_longitude(self, value): if -180 <= value <= 180: return value raise serializers.ValidationError(_('Invalid value')) def validate(self, attrs): # validate coordinates latitude = attrs.pop('latitude', None) longitude = attrs.pop('longitude', None) if latitude is not None and longitude is not None: attrs['coordinates'] = Point(longitude, latitude) return attrs class AddressDetailSerializer(AddressBaseSerializer): """Address serializer.""" city_id = serializers.PrimaryKeyRelatedField( source='city', write_only=True, queryset=models.City.objects.all()) city = CitySerializer(read_only=True) class Meta(AddressBaseSerializer.Meta): """Meta class.""" fields = AddressBaseSerializer.Meta.fields + ( 'city_id', 'city', ) class WineRegionBaseSerializer(serializers.ModelSerializer): """Wine region serializer.""" country = CountrySerializer() class Meta: """Meta class.""" model = models.WineRegion fields = [ 'id', 'name', 'country', ] class WineSubRegionBaseSerializer(serializers.ModelSerializer): """Wine sub region serializer.""" class Meta: """Meta class.""" model = models.WineSubRegion fields = [ 'id', 'name', ] class WineRegionSerializer(WineRegionBaseSerializer): """Wine region w/ subregion serializer""" wine_sub_region = WineSubRegionBaseSerializer(allow_null=True, many=True) class Meta(WineRegionBaseSerializer.Meta): fields = WineRegionBaseSerializer.Meta.fields + [ 'wine_sub_region' ]