"""Tag serializers.""" from rest_framework import serializers from establishment.models import (Establishment, EstablishmentType, EstablishmentSubType) from news.models import News, NewsType from tag import models from utils.exceptions import (ObjectAlreadyAdded, BindingObjectNotFound, RemovedBindingObjectNotFound) from utils.serializers import TranslatedField class TagBaseSerializer(serializers.ModelSerializer): """Serializer for model Tag.""" # todo: refactor this # label_translated = TranslatedField() label_translated = serializers.CharField(source='value', read_only=True, allow_null=True) index_name = serializers.CharField(source='value', read_only=True, allow_null=True) class Meta: """Meta class.""" model = models.Tag fields = ( 'id', 'label_translated', 'index_name', ) class TagBackOfficeSerializer(TagBaseSerializer): """Serializer for Tag model for Back office users.""" class Meta(TagBaseSerializer.Meta): """Meta class.""" fields = TagBaseSerializer.Meta.fields + ( 'label', 'category' ) class TagCategoryBaseSerializer(serializers.ModelSerializer): """Serializer for model TagCategory.""" # todo: refactor this # label_translated = TranslatedField() label_translated = serializers.CharField(source='index_name', read_only=True, allow_null=True) tags = TagBaseSerializer(many=True, read_only=True) class Meta: """Meta class.""" model = models.TagCategory fields = ( 'id', 'label_translated', 'index_name', 'tags', ) class TagCategoryBackOfficeDetailSerializer(TagCategoryBaseSerializer): """Tag Category detail serializer for back-office users.""" country_translated = TranslatedField(source='country.name_translated') class Meta(TagCategoryBaseSerializer.Meta): """Meta class.""" fields = TagCategoryBaseSerializer.Meta.fields + ( 'label', 'country', 'country_translated', ) class TagBindObjectSerializer(serializers.Serializer): """Serializer for binding tag category and objects""" ESTABLISHMENT = 'establishment' NEWS = 'news' TYPE_CHOICES = ( (ESTABLISHMENT, 'Establishment type'), (NEWS, 'News type'), ) 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') tag = view.get_object() attrs['tag'] = tag if obj_type == self.ESTABLISHMENT: establishment = Establishment.objects.filter(pk=obj_id).first() if not establishment: raise BindingObjectNotFound() if request.method == 'POST' and tag.establishments.filter( pk=establishment.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not tag.establishments.filter( pk=establishment.pk).exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = establishment elif obj_type == self.NEWS: news = News.objects.filter(pk=obj_id).first() if not news: raise BindingObjectNotFound() if request.method == 'POST' and tag.news.filter(pk=news.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not tag.news.filter( pk=news.pk).exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = news return attrs class TagCategoryBindObjectSerializer(serializers.Serializer): """Serializer for binding tag category and objects""" ESTABLISHMENT_TYPE = 'establishment_type' NEWS_TYPE = 'news_type' TYPE_CHOICES = ( (ESTABLISHMENT_TYPE, 'Establishment type'), (NEWS_TYPE, 'News type'), ) 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') tag_category = view.get_object() attrs['tag_category'] = tag_category if obj_type == self.ESTABLISHMENT_TYPE: establishment_type = EstablishmentType.objects.filter(pk=obj_id).\ first() if not establishment_type: raise BindingObjectNotFound() if request.method == 'POST' and tag_category.establishment_types.\ filter(pk=establishment_type.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not tag_category.\ establishment_types.filter(pk=establishment_type.pk).\ exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = establishment_type elif obj_type == self.NEWS_TYPE: news_type = NewsType.objects.filter(pk=obj_id).first() if not news_type: raise BindingObjectNotFound() if request.method == 'POST' and tag_category.news_types.\ filter(pk=news_type.pk).exists(): raise ObjectAlreadyAdded() if request.method == 'DELETE' and not tag_category.news_types.\ filter(pk=news_type.pk).exists(): raise RemovedBindingObjectNotFound() attrs['related_object'] = news_type return attrs