288 lines
8.9 KiB
Python
288 lines
8.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
|
|
from news.models import NewsType
|
|
from tag import models
|
|
from utils.exceptions import BindingObjectNotFound, ObjectAlreadyAdded, RemovedBindingObjectNotFound
|
|
from utils.serializers import TranslatedField
|
|
from utils.models import get_default_locale, get_language, to_locale
|
|
|
|
|
|
def translate_obj(obj):
|
|
if not obj.translation or not isinstance(obj.translation.text, dict):
|
|
return None
|
|
try:
|
|
field = obj.translation.text
|
|
return field.get(to_locale(get_language()),
|
|
field.get(get_default_locale(),
|
|
next(iter(field.values()))))
|
|
except StopIteration:
|
|
return None
|
|
|
|
|
|
class TagBaseSerializer(serializers.ModelSerializer):
|
|
"""Serializer for model Tag."""
|
|
|
|
def get_extra_kwargs(self):
|
|
return super().get_extra_kwargs()
|
|
|
|
index_name = serializers.CharField(source='value', read_only=True, allow_null=True)
|
|
label_translated = serializers.SerializerMethodField(read_only=True, allow_null=True)
|
|
|
|
def get_label_translated(self, obj):
|
|
return translate_obj(obj)
|
|
|
|
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 = serializers.SerializerMethodField(read_only=True, allow_null=True)
|
|
|
|
def get_label_translated(self, obj):
|
|
return translate_obj(obj)
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
model = models.TagCategory
|
|
fields = (
|
|
'id',
|
|
'index_name',
|
|
)
|
|
|
|
|
|
class TagCategoryBaseSerializer(serializers.ModelSerializer):
|
|
"""Serializer for model TagCategory."""
|
|
|
|
tags = TagBaseSerializer(many=True, allow_null=True)
|
|
label_translated = serializers.SerializerMethodField(read_only=True, allow_null=True)
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
model = models.TagCategory
|
|
fields = (
|
|
'id',
|
|
'label_translated',
|
|
'index_name',
|
|
'tags',
|
|
)
|
|
|
|
def get_label_translated(self, obj):
|
|
return translate_obj(obj)
|
|
|
|
|
|
class FiltersTagCategoryBaseSerializer(serializers.ModelSerializer):
|
|
"""Serializer for model TagCategory."""
|
|
|
|
filters = SerializerMethodField()
|
|
param_name = SerializerMethodField()
|
|
type = SerializerMethodField()
|
|
label_translated = serializers.SerializerMethodField(allow_null=True, read_only=True)
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
model = models.TagCategory
|
|
fields = (
|
|
'id',
|
|
'label_translated',
|
|
'index_name',
|
|
'param_name',
|
|
'type',
|
|
'filters',
|
|
)
|
|
|
|
def get_type(self, obj):
|
|
return obj in ['open_now', ]
|
|
|
|
def get_param_name(self, obj):
|
|
if obj.index_name == 'wine-color':
|
|
return 'wine_colors_id__in'
|
|
return 'tags_id__in'
|
|
|
|
def get_label_translated(self, obj):
|
|
return translate_obj(obj)
|
|
|
|
def get_fields(self, *args, **kwargs):
|
|
fields = super(FiltersTagCategoryBaseSerializer, self).get_fields()
|
|
|
|
if self.get_type(self):
|
|
fields.pop('filters', None)
|
|
else:
|
|
fields.pop('type', None)
|
|
|
|
return fields
|
|
|
|
def get_filters(self, obj):
|
|
query_params = dict(self.context['request'].query_params)
|
|
|
|
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 = serializers.SerializerMethodField(allow_null=True, read_only=True)
|
|
value_type_display = serializers.CharField(source='get_value_type_display',
|
|
read_only=True)
|
|
|
|
def get_label_translated(self, obj):
|
|
return translate_obj(obj)
|
|
|
|
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
|