gault-millau/apps/tag/serializers.py
2019-12-03 19:31:05 +03:00

224 lines
7.1 KiB
Python

"""Tag serializers."""
from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
from establishment.models import (Establishment, EstablishmentType,
EstablishmentSubType)
from news.models import News, NewsType
from tag import models
from tag.models import Tag
from utils.exceptions import (ObjectAlreadyAdded, BindingObjectNotFound,
RemovedBindingObjectNotFound)
from utils.serializers import TranslatedField
class TagBaseSerializer(serializers.ModelSerializer):
"""Serializer for model Tag."""
def get_extra_kwargs(self):
return super().get_extra_kwargs()
label_translated = TranslatedField()
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 TagCategoryProductSerializer(serializers.ModelSerializer):
"""SHORT Serializer for TagCategory"""
label_translated = TranslatedField()
class Meta:
"""Meta class."""
model = models.TagCategory
fields = (
'id',
'label_translated',
'index_name',
)
class TagCategoryBaseSerializer(serializers.ModelSerializer):
"""Serializer for model TagCategory."""
label_translated = TranslatedField()
tags = SerializerMethodField()
class Meta:
"""Meta class."""
model = models.TagCategory
fields = (
'id',
'label_translated',
'index_name',
'tags',
)
def get_tags(self, obj):
query_params = dict(self.context['request'].query_params)
if len(query_params) > 1:
return None
tags = Tag.objects.all()
if 'establishment_type' in query_params:
types = query_params['establishment_type']
tags = tags.filter(establishments__establishment_type__index_name__in=types).distinct()
elif 'product_type' in query_params:
types = query_params['product_type']
tags = tags.filter(products__product_type__index_name__in=types).distinct()
return TagBaseSerializer(instance=tags, many=True, read_only=True).data
class TagCategoryShortSerializer(serializers.ModelSerializer):
"""Serializer for model TagCategory."""
label_translated = TranslatedField()
value_type_display = serializers.CharField(source='get_value_type_display',
read_only=True)
class Meta(TagCategoryBaseSerializer.Meta):
"""Meta class."""
fields = [
'label_translated',
'value_type_display',
]
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