"""Product app serializers.""" from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from comment.models import Comment from comment.serializers import CommentSerializer from establishment.serializers import EstablishmentProductShortSerializer from establishment.serializers.common import _EstablishmentAddressShortSerializer from location.serializers import WineOriginRegionBaseSerializer,\ WineOriginBaseSerializer, EstablishmentWineOriginBaseSerializer from main.serializers import AwardSerializer from product import models from review.serializers import ReviewShortSerializer from tag.serializers import TagBaseSerializer, TagCategoryProductSerializer from utils import exceptions as utils_exceptions from utils.serializers import TranslatedField, FavoritesCreateSerializer, ImageBaseSerializer class ProductTagSerializer(TagBaseSerializer): """Serializer for model Tag.""" category = TagCategoryProductSerializer(read_only=True) class Meta(TagBaseSerializer.Meta): """Meta class.""" fields = TagBaseSerializer.Meta.fields + ( 'category', ) class ProductSubTypeBaseSerializer(serializers.ModelSerializer): """ProductSubType base serializer""" name_translated = TranslatedField() index_name_display = serializers.CharField(source='get_index_name_display', read_only=True) class Meta: model = models.ProductSubType fields = [ 'id', 'name_translated', 'index_name_display', ] class ProductTypeBaseSerializer(serializers.ModelSerializer): """ProductType base serializer""" name_translated = TranslatedField() class Meta: model = models.ProductType fields = [ 'id', 'name_translated', 'index_name', ] class ProductClassificationBaseSerializer(serializers.ModelSerializer): """Serializer for model ProductClassification.""" name = serializers.CharField(source='classification_type.name') class Meta: """Meta class.""" model = models.ProductClassification fields = ( 'name', ) class ProductStandardBaseSerializer(serializers.ModelSerializer): """Serializer for model ProductStandard.""" standard_type = serializers.CharField(source='get_standard_type_display') class Meta: """Meta class.""" model = models.ProductStandard fields = ( 'name', 'standard_type', ) class ProductBaseSerializer(serializers.ModelSerializer): """Product base serializer.""" name = serializers.CharField(source='display_name', read_only=True) product_type = ProductTypeBaseSerializer(read_only=True) subtypes = ProductSubTypeBaseSerializer(many=True, read_only=True) establishment_detail = EstablishmentProductShortSerializer(source='establishment', read_only=True) tags = ProductTagSerializer(source='related_tags', many=True, read_only=True) wine_regions = WineOriginRegionBaseSerializer(many=True, source='wine_origins', read_only=True) wine_colors = TagBaseSerializer(many=True, read_only=True) preview_image_url = serializers.URLField(allow_null=True, read_only=True) in_favorites = serializers.BooleanField(allow_null=True) wine_origins = EstablishmentWineOriginBaseSerializer(many=True, read_only=True) class Meta: """Meta class.""" model = models.Product fields = [ 'id', 'slug', 'name', 'product_type', 'subtypes', 'public_mark', 'establishment_detail', 'vintage', 'tags', 'preview_image_url', 'wine_regions', 'wine_colors', 'in_favorites', 'wine_origins', ] class ProductDetailSerializer(ProductBaseSerializer): """Product detail serializer.""" description_translated = TranslatedField() establishment_detail = _EstablishmentAddressShortSerializer(source='establishment', read_only=True) review = ReviewShortSerializer(source='last_published_review', read_only=True) awards = AwardSerializer(many=True, read_only=True) classifications = ProductClassificationBaseSerializer(many=True, read_only=True) standards = ProductStandardBaseSerializer(many=True, read_only=True) wine_origins = WineOriginBaseSerializer(many=True, read_only=True) bottles_produced = TagBaseSerializer(many=True, read_only=True) sugar_contents = TagBaseSerializer(many=True, read_only=True) grape_variety = TagBaseSerializer(many=True, read_only=True) bottle_sizes = TagBaseSerializer(many=True, read_only=True) alcohol_percentage = TagBaseSerializer(read_only=True) image_url = serializers.URLField(allow_null=True, read_only=True) new_image = ImageBaseSerializer(source='crop_main_image', allow_null=True, read_only=True) class Meta(ProductBaseSerializer.Meta): fields = ProductBaseSerializer.Meta.fields + [ 'description_translated', 'review', 'awards', 'classifications', 'standards', 'wine_origins', 'bottles_produced', 'sugar_contents', 'image_url', 'new_image', 'grape_variety', 'average_price', 'bottle_sizes', 'alcohol_percentage', ] class ProductFavoritesCreateSerializer(FavoritesCreateSerializer): """Serializer to create favorite object w/ model Product.""" def validate(self, attrs): """Overridden validate method""" # Check product object product_qs = models.Product.objects.filter(slug=self.slug) # Check product obj by slug from lookup_kwarg if not product_qs.exists(): raise serializers.ValidationError({'detail': _('Object not found.')}) else: product = product_qs.first() # Check existence in favorites if product.favorites.filter(user=self.user).exists(): raise utils_exceptions.FavoritesError() attrs['product'] = product return attrs def create(self, validated_data, *args, **kwargs): """Overridden create method""" validated_data.update({ 'user': self.user, 'content_object': validated_data.pop('product') }) return super().create(validated_data) class ProductCommentCreateSerializer(CommentSerializer): """Create comment serializer""" mark = serializers.IntegerField() class Meta: """Serializer for model Comment""" model = Comment fields = [ 'id', 'created', 'text', 'mark', 'nickname', 'profile_pic', ] def validate(self, attrs): """Override validate method""" # Check product object product_slug = self.context.get('request').parser_context.get('kwargs').get('slug') product_qs = models.Product.objects.filter(slug=product_slug) if not product_qs.exists(): raise serializers.ValidationError({'detail': _('Product not found.')}) attrs['product'] = product_qs.first() return attrs def create(self, validated_data, *args, **kwargs): """Override create method""" validated_data.update({ 'user': self.context.get('request').user, 'content_object': validated_data.pop('product') }) return super().create(validated_data)