gault-millau/apps/search_indexes/serializers.py
2020-01-31 13:06:03 +03:00

370 lines
12 KiB
Python

"""Search indexes serializers."""
from json import loads
from django_elasticsearch_dsl_drf.serializers import DocumentSerializer
from elasticsearch_dsl import AttrDict
from rest_framework import serializers
from news.serializers import NewsTypeSerializer
from search_indexes.documents import EstablishmentDocument, NewsDocument
from search_indexes.documents.product import ProductDocument
from search_indexes.utils import get_translated_value
class TagsDocumentSerializer(serializers.Serializer):
"""Tags serializer for ES Document."""
id = serializers.IntegerField()
label_translated = serializers.SerializerMethodField()
def get_label_translated(self, obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('label'))
return get_translated_value(obj.label)
class EstablishmentTypeSerializer(serializers.Serializer):
"""Establishment type serializer for ES Document"""
id = serializers.IntegerField()
name_translated = serializers.SerializerMethodField()
index_name = serializers.CharField()
default_image = serializers.CharField()
preview_image_url = serializers.CharField()
def get_name_translated(self, obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
class ProductSubtypeDocumentSerializer(serializers.Serializer):
"""Product subtype serializer for ES Document."""
id = serializers.IntegerField()
name_translated = serializers.SerializerMethodField()
default_image = serializers.CharField()
preview_image_url = serializers.CharField()
def get_name_translated(self, obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
class WineRegionCountryDocumentSerialzer(serializers.Serializer):
"""Wine region country ES document serializer."""
id = serializers.IntegerField()
code = serializers.CharField()
name_translated = serializers.SerializerMethodField()
@staticmethod
def get_name_translated(obj):
return get_translated_value(obj.name)
def get_attribute(self, instance):
return instance.country if instance and instance.country else None
class WineRegionDocumentSerializer(serializers.Serializer):
"""Wine region ES document serializer."""
id = serializers.IntegerField()
name = serializers.CharField()
country = WineRegionCountryDocumentSerialzer(allow_null=True)
def get_attribute(self, instance):
return instance.wine_region if instance and instance.wine_region else None
class WineSubRegionDocumentSerializer(serializers.Serializer):
"""Wine region ES document serializer."""
id = serializers.IntegerField()
name = serializers.CharField()
def get_attribute(self, instance):
return instance.wine_sub_region if instance and instance.wine_sub_region else None
class TagDocumentSerializer(serializers.Serializer):
"""Tag ES document serializer,"""
id = serializers.IntegerField()
label_translated = serializers.SerializerMethodField()
index_name = serializers.CharField(source='value')
@staticmethod
def get_label_translated(obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('label'))
return get_translated_value(obj.label)
class ProductTypeSerializer(serializers.Serializer):
"""Product type ES document serializer."""
id = serializers.IntegerField()
index_name = serializers.CharField()
name_translated = serializers.SerializerMethodField()
default_image = serializers.CharField()
preview_image_url = serializers.CharField()
@staticmethod
def get_name_translated(obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
def get_attribute(self, instance):
return instance.product_type if instance and instance.product_type else None
class CityDocumentShortSerializer(serializers.Serializer):
"""City serializer for ES Document,"""
id = serializers.IntegerField()
code = serializers.CharField(allow_null=True)
# todo: index and use name dict field
name_translated = serializers.SerializerMethodField()
@staticmethod
def get_name_translated(obj):
return get_translated_value(loads(obj.name)) if obj.name else None
class CountryDocumentSerializer(serializers.Serializer):
id = serializers.IntegerField()
code = serializers.CharField(allow_null=True)
svg_image = serializers.CharField()
name_translated = serializers.SerializerMethodField()
@staticmethod
def get_name_translated(obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
class AnotherCityDocumentShortSerializer(CityDocumentShortSerializer):
country = CountryDocumentSerializer()
def to_representation(self, instance):
if instance != AttrDict(d={}) or \
(isinstance(instance, dict) and len(instance) != 0):
return super().to_representation(instance)
return None
class AddressDocumentSerializer(serializers.Serializer):
"""Address serializer for ES Document."""
id = serializers.IntegerField()
city = CityDocumentShortSerializer()
street_name_1 = serializers.CharField()
street_name_2 = serializers.CharField()
number = serializers.IntegerField()
postal_code = serializers.CharField()
latitude = serializers.FloatField(allow_null=True, source='coordinates.lat')
longitude = serializers.FloatField(allow_null=True, source='coordinates.lon')
geo_lon = serializers.FloatField(allow_null=True, source='coordinates.lon')
geo_lat = serializers.FloatField(allow_null=True, source='coordinates.lat')
# todo: refator
def to_representation(self, instance):
if instance != AttrDict(d={}) or \
(isinstance(instance, dict) and len(instance) != 0):
return super().to_representation(instance)
return None
class PSAddressDocumentSerializer(serializers.Serializer):
"""Address serializer for ES Document."""
id = serializers.IntegerField()
street_name_1 = serializers.CharField()
postal_code = serializers.CharField()
class ProductEstablishmentSerializer(serializers.Serializer):
"""Related to Product Establishment ES document serializer."""
id = serializers.IntegerField()
name = serializers.CharField()
slug = serializers.CharField()
index_name = serializers.CharField()
city = AnotherCityDocumentShortSerializer()
address = PSAddressDocumentSerializer(allow_null=True)
def get_attribute(self, instance):
return instance.establishment if instance and instance.establishment else None
class ScheduleDocumentSerializer(serializers.Serializer):
"""Schedule serializer for ES Document"""
id = serializers.IntegerField()
weekday = serializers.IntegerField()
weekday_display = serializers.CharField()
closed_at = serializers.CharField()
opening_at = serializers.CharField()
class InFavoritesMixin(DocumentSerializer):
"""Append in_favorites field."""
in_favorites = serializers.SerializerMethodField()
def get_in_favorites(self, obj):
request = self.context['request']
user = request.user
if user.is_authenticated:
return user.id in obj.favorites_for_users
return False
class Meta:
"""Meta class."""
_abstract = True
class NewsDocumentSerializer(InFavoritesMixin, DocumentSerializer):
"""News document serializer."""
title_translated = serializers.SerializerMethodField(allow_null=True)
subtitle_translated = serializers.SerializerMethodField(allow_null=True)
news_type = NewsTypeSerializer()
tags = TagsDocumentSerializer(many=True, source='visible_tags')
slug = serializers.SerializerMethodField(allow_null=True)
class Meta:
"""Meta class."""
document = NewsDocument
fields = (
'id',
'title_translated',
'subtitle_translated',
'is_highlighted',
'image_url',
'preview_image_url',
'news_type',
'tags',
'start',
'slug',
)
@staticmethod
def get_slug(obj):
return get_translated_value(loads(obj.slugs))
@staticmethod
def get_title_translated(obj):
return get_translated_value(obj.title)
@staticmethod
def get_subtitle_translated(obj):
return get_translated_value(obj.subtitle)
class WineOriginSerializer(serializers.Serializer):
"""Wine origin serializer."""
wine_region = WineRegionDocumentSerializer()
wine_sub_region = WineSubRegionDocumentSerializer(allow_null=True)
class EstablishmentDocumentSerializer(InFavoritesMixin, DocumentSerializer):
"""Establishment document serializer."""
type = EstablishmentTypeSerializer(source='establishment_type')
subtypes = EstablishmentTypeSerializer(many=True, source='establishment_subtypes')
address = AddressDocumentSerializer(allow_null=True)
tags = TagsDocumentSerializer(many=True, source='visible_tags')
restaurant_category = TagsDocumentSerializer(many=True, allow_null=True)
restaurant_cuisine = TagsDocumentSerializer(many=True, allow_null=True)
distillery_type = TagsDocumentSerializer(many=True, allow_null=True)
artisan_category = TagsDocumentSerializer(many=True, allow_null=True)
schedule = ScheduleDocumentSerializer(many=True, allow_null=True)
wine_origins = WineOriginSerializer(many=True)
class Meta:
"""Meta class."""
document = EstablishmentDocument
fields = (
'id',
'name',
'transliterated_name',
'index_name',
'price_level',
'toque_number',
'public_mark',
'slug',
'preview_image',
'address',
'tags',
'restaurant_category',
'restaurant_cuisine',
'artisan_category',
'schedule',
'works_noon',
'works_evening',
'works_at_weekday',
'tz',
'wine_origins',
# 'works_now',
# 'collections',
'type',
'subtypes',
'distillery_type',
)
class EstablishmentBackOfficeDocumentSerializer(EstablishmentDocumentSerializer):
class Meta(EstablishmentDocumentSerializer.Meta):
document = EstablishmentDocumentSerializer.Meta.document
fields = EstablishmentDocumentSerializer.Meta.fields + (
'created',
)
class ProductDocumentSerializer(InFavoritesMixin):
"""Product document serializer"""
tags = TagsDocumentSerializer(many=True, source='related_tags')
subtypes = ProductSubtypeDocumentSerializer(many=True, allow_null=True)
wine_colors = TagDocumentSerializer(many=True)
grape_variety = TagDocumentSerializer(many=True)
product_type = ProductTypeSerializer(allow_null=True)
establishment_detail = ProductEstablishmentSerializer(source='establishment', allow_null=True)
wine_origins = WineOriginSerializer(many=True)
class Meta:
"""Meta class."""
document = ProductDocument
fields = (
'id',
'category',
'preview_image_url',
'name',
'available',
'public_mark',
'slug',
'old_id',
'state',
'old_unique_key',
'vintage',
'tags',
'product_type',
'subtypes',
'wine_colors',
'grape_variety',
'average_price',
'created',
'wine_origins',
)