gault-millau/apps/tag/serializers.py
2019-12-04 09:23:21 +03:00

225 lines
6.9 KiB
Python

"""Tag serializers."""
from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
from establishment.models import (Establishment, EstablishmentType)
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."""
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 []
params = {}
if 'establishment_type' in query_params:
params = {
'establishments__isnull': False,
}
elif 'product_type' in query_params:
params = {
'products__isnull': False,
}
tags = obj.tags.filter(**params).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