from rest_framework import serializers from collection import models from collection.models import Guide from collection.serializers.common import CollectionBaseSerializer from establishment.models import Establishment from location.models import Country from location.serializers import CountrySimpleSerializer from product.models import Product from utils.exceptions import ( BindingObjectNotFound, ObjectAlreadyAdded, RemovedBindingObjectNotFound, ) class CollectionBackOfficeSerializer(CollectionBaseSerializer): """Collection back serializer.""" country_id = serializers.PrimaryKeyRelatedField( source='country', write_only=True, queryset=Country.objects.all()) collection_type_display = serializers.CharField( source='get_collection_type_display', read_only=True) country = CountrySimpleSerializer(read_only=True) count_related_objects = serializers.IntegerField(read_only=True) related_object_names = serializers.ListField(read_only=True) class Meta: model = models.Collection fields = CollectionBaseSerializer.Meta.fields + [ 'id', 'name', 'collection_type', 'collection_type_display', 'is_publish', 'on_top', 'country', 'country_id', # 'block_size', 'description', 'slug', # 'start', # 'end', 'count_related_objects', 'related_object_names', 'rank', ] extra_kwargs = { 'slug': {'read_only': True}, } class CollectionBindObjectSerializer(serializers.Serializer): """Serializer for binding collection and objects""" ESTABLISHMENT = 'establishment' PRODUCT = 'product' TYPE_CHOICES = ( (ESTABLISHMENT, 'Establishment'), (PRODUCT, 'Product'), ) type = serializers.ChoiceField(TYPE_CHOICES) object_id = serializers.IntegerField() def validate(self, attrs): view = self.context.get('view') request = self.context.get('request') obj_type = attrs.get('type') obj_id = attrs.get('object_id') collection = view.get_object() attrs['collection'] = collection if obj_type == self.ESTABLISHMENT: establishment = Establishment.objects.filter(pk=obj_id). \ first() if not establishment: raise BindingObjectNotFound() if request.method == 'POST' and collection.establishments. \ filter(pk=establishment.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not collection. \ establishments.filter(pk=establishment.pk). \ exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = establishment elif obj_type == self.PRODUCT: product = Product.objects.filter(pk=obj_id).first() if not product: raise BindingObjectNotFound() if request.method == 'POST' and collection.products. \ filter(pk=product.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not collection.products. \ filter(pk=product.pk).exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = product return attrs class GuideBindObjectSerializer(serializers.Serializer): """Serializer for binding guide and objects""" GUIDE = 'guide' PRODUCT = 'product' TYPE_CHOICES = ( (GUIDE, 'Guide'), (PRODUCT, 'Product'), ) type = serializers.ChoiceField(TYPE_CHOICES) object_id = serializers.IntegerField() def validate(self, attrs): view = self.context.get('view') request = self.context.get('request') obj_type = attrs.get('type') obj_id = attrs.get('object_id') guide = view.get_object() attrs['guide'] = guide if obj_type == self.GUIDE: guide = Guide.objects.filter(pk=obj_id).first() if not guide: raise BindingObjectNotFound() if request.method == 'POST' and guide.establishments.filter(pk=guide.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not guide. \ establishments.filter(pk=guide.pk). \ exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = guide elif obj_type == self.PRODUCT: product = Product.objects.filter(pk=obj_id).first() if not product: raise BindingObjectNotFound() if request.method == 'POST' and guide.products. \ filter(pk=product.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not guide.products. \ filter(pk=product.pk).exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = product return attrs