"""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 EstablishmentShortSerializer, EstablishmentProductSerializer, EstablishmentProductShortSerializer from gallery.models import Image from product import models from review.serializers import ReviewShortSerializer from utils import exceptions as utils_exceptions from utils.serializers import TranslatedField, FavoritesCreateSerializer, ImageBaseSerializer from main.serializers import AwardSerializer from location.serializers import WineRegionBaseSerializer, WineSubRegionBaseSerializer from tag.serializers import TagBaseSerializer, TagCategoryProductSerializer 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_region = WineRegionBaseSerializer(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) class Meta: """Meta class.""" model = models.Product fields = [ 'id', 'slug', 'name', 'product_type', 'subtypes', 'public_mark', 'establishment_detail', 'vintage', 'tags', 'preview_image_url', 'wine_region', 'wine_colors', 'in_favorites', ] class ProductDetailSerializer(ProductBaseSerializer): """Product detail serializer.""" description_translated = TranslatedField() establishment_detail = EstablishmentShortSerializer(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_sub_region = WineSubRegionBaseSerializer(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) 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_sub_region', 'bottles_produced', 'sugar_contents', 'image_url', 'new_image', 'grape_variety', ] 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)