updated serializer

This commit is contained in:
Anatoly 2019-11-29 13:26:05 +03:00
parent eaeebae72a
commit 0fb28467fb
3 changed files with 133 additions and 78 deletions

View File

@ -1,3 +1,3 @@
FROM mdillon/postgis:9.5
FROM mdillon/postgis:latest
RUN localedef -i ru_RU -c -f UTF-8 -A /usr/share/locale/locale.alias ru_RU.UTF-8
ENV LANG ru_RU.utf8

View File

@ -197,7 +197,7 @@ class WineRegionQuerySet(models.QuerySet):
return self.exclude(wines__isnull=value)
class WineRegion(models.Model, TranslatedFieldsMixin):
class WineRegion(TranslatedFieldsMixin, models.Model):
"""Wine region model."""
name = models.CharField(_('name'), max_length=255)
country = models.ForeignKey(Country, on_delete=models.PROTECT,

View File

@ -6,9 +6,11 @@ from rest_framework import serializers
from collection.models import Guide, GuideType, GuideFilter
from establishment.models import EstablishmentType
from location.models import Country, Region
from location.models import Country, Region, WineRegion
from main.models import SiteSettings
from transfer.mixins import TransferSerializerMixin
from translation.models import Language
from review.models import Review
class GuideSerializer(TransferSerializerMixin):
@ -70,9 +72,6 @@ class GuideFilterSerializer(TransferSerializerMixin):
regions = serializers.CharField(allow_null=True)
subregions = serializers.CharField(allow_null=True)
wine_regions = serializers.CharField(allow_null=True)
wine_classifications = serializers.CharField(allow_null=True)
wine_colors = serializers.CharField(allow_null=True)
wine_types = serializers.CharField(allow_null=True)
locales = serializers.CharField(allow_null=True)
states = serializers.CharField(allow_null=True)
@ -91,9 +90,6 @@ class GuideFilterSerializer(TransferSerializerMixin):
'regions',
'subregions',
'wine_regions',
'wine_classifications',
'wine_colors',
'wine_types',
'max_mark',
'min_mark',
'marks_only',
@ -112,12 +108,6 @@ class GuideFilterSerializer(TransferSerializerMixin):
loader.add_constructor('!ruby/hash:ActiveSupport::HashWithIndifferentAccess', convert_entry)
return yaml.load(raw_value, Loader=loader) if raw_value else None
@staticmethod
def get_country_alpha_2(country_code_alpha3: str):
country = countries.get(alpha_3=country_code_alpha3.upper())
return {'code_alpha_2': country.alpha2.lower() if country else None,
'name': country.name if country else None,}
@staticmethod
def parse_dictionary(dictionary: dict):
"""
@ -140,19 +130,20 @@ class GuideFilterSerializer(TransferSerializerMixin):
return list(chain.from_iterable(l))
def get_country(self, code_alpha_3: str) -> Country:
country = self.get_country_alpha_2(code_alpha_3)
country_name = country['name']
country_code = country['code_alpha_2']
if country_name and country_code:
country, _ = Country.objects.get_or_create(
code__icontains=country_code,
name__contains={'en-GB': country_name},
defaults={
'code': country_code,
'name': {'en-GB': country_name}
}
)
return country
country = countries.get(alpha_3=code_alpha_3.upper())
if country:
country_name = country.name
country_code = country.alpha_2
if country_name and country_code:
country, _ = Country.objects.get_or_create(
code__icontains=country_code,
name__contains={'en-GB': country_name},
defaults={
'code': country_code,
'name': {'en-GB': country_name}
}
)
return country
def get_region(self, region_code_alpha_3: str,
country_code_alpha_3: str,
@ -162,20 +153,21 @@ class GuideFilterSerializer(TransferSerializerMixin):
region_qs = Region.objects.filter(code__iexact=region_code_alpha_3,
country__code__iexact=country_code_alpha_2)
if region_qs.exists():
return region_qs.first()
# If region isn't existed, check sub region for parent_code (region code)
if not region_qs.exists() and sub_region_code_alpha_3:
if sub_region_code_alpha_3:
# sub region
subdivision = subdivisions.get(
code=f"{country_code_alpha_2}-{sub_region_code_alpha_3}")
if subdivision:
subdivision_region = subdivisions.get(parent_code=subdivision.parent_code)
subdivision_region = subdivisions.get(code=subdivision.parent_code)
obj = Region.objects.create(
name=subdivision_region.name,
code=subdivision_region.code,
country=country)
return obj
else:
return region_qs.first()
def validate_year(self, value):
return self.parse_ruby_helper(value)
@ -189,7 +181,7 @@ class GuideFilterSerializer(TransferSerializerMixin):
def validate_regions(self, value):
return self.parse_ruby_helper(value)
def validate_sub_regions(self, value):
def validate_subregions(self, value):
return self.parse_ruby_helper(value)
def validate_wine_regions(self, value):
@ -215,69 +207,132 @@ class GuideFilterSerializer(TransferSerializerMixin):
regions = attrs.pop('regions')
attrs['old_id'] = attrs.pop('id')
attrs['review_vintage_json'] = self.get_review_vintage(self.attrs.pop('year'))
attrs['review_vintage_json'] = self.get_review_vintage(attrs.pop('year'))
attrs['establishment_type_json'] = self.get_establishment_type_ids(
self.attrs.pop('establishment_type'))
attrs['country_code_json'] = self.get_country_ids(attrs.pop('country_json'))
attrs['region_json'] = self.get_region_ids(regions, sub_regions)
attrs['sub_region_json'] = self.get_sub_region_ids(regions, sub_regions)
attrs.pop('establishment_type'))
attrs['country_code_json'] = self.get_country_ids(attrs.pop('countries'))
attrs['region_json'] = self.get_region_ids(regions=regions,
sub_regions=sub_regions)
attrs['sub_region_json'] = self.get_sub_region_ids(sub_regions)
attrs['wine_region_json'] = self.get_wine_region_ids(attrs.pop('wine_regions'))
attrs['with_mark'] = attrs.pop('marks_only')
attrs['locale_json'] = self.get_locale_ids(attrs.pop('locales'))
attrs['review_state_json'] = self.get_review_state(attrs.pop('states'))
attrs['guide'] = self.get_guide(attrs.pop('guide_id'))
return attrs
def get_review_vintage(self, year):
return {'vintage': [int(i) for i in set(year) if i.isdigit()]}
if hasattr(year, '__iter__'):
return {'vintage': set(int(i) for i in set(year) if i.isdigit())}
return {'vintage': {year}}
def get_establishment_type_ids(self, establishment_types):
establishment_type_ids = []
for establishment_type in establishment_types:
establishment_type_qs = EstablishmentType.objects.filter(index_name__iexact=establishment_type)
if not establishment_type_qs.exists():
obj = EstablishmentType.objects.create(
name={'en-GB': establishment_type.capitalize},
index_name=establishment_type.lower())
if establishment_types:
for establishment_type in establishment_types:
establishment_type_qs = EstablishmentType.objects.filter(index_name__iexact=establishment_type)
if not establishment_type_qs.exists():
obj = EstablishmentType.objects.create(
name={'en-GB': establishment_type.capitalize()},
index_name=establishment_type.lower())
else:
obj = establishment_type_qs.first()
establishment_type_ids.append(obj.id)
return {'id': establishment_type_ids}
return {'id': set(establishment_type_ids)}
def get_country_ids(self, country_codes_alpha_3):
country_ids = []
for code_alpha_3 in country_codes_alpha_3:
country_ids.append(self.get_country(code_alpha_3).id)
return {'id': country_ids}
if country_codes_alpha_3:
for code_alpha_3 in country_codes_alpha_3:
country = self.get_country(code_alpha_3)
if not country:
raise serializers.ValidationError({'detail': f'Country with alpha code 3 -'
f'{code_alpha_3}, is not found.'})
country_ids.append(country.id)
return {'id': set(country_ids)}
def get_region_ids(self, regions, sub_regions):
region_ids = []
for country_code_alpha_3 in regions:
region_codes = regions[country_code_alpha_3]
for region_code_alpha_3 in region_codes:
region = self.get_region(
region_code_alpha_3=region_code_alpha_3,
country_code_alpha_3=country_code_alpha_3,
sub_region_code_alpha_3=sub_regions[country_code_alpha_3][region_code_alpha_3])
if region:
region_ids.append(region.id)
if regions:
for country_code_alpha_3 in regions:
for region_code_alpha_3 in regions[country_code_alpha_3]:
# Get region from sub region code.
if not sub_regions or country_code_alpha_3 not in sub_regions:
raise serializers.ValidationError({'detail': f'Sub regions is blanked.'})
if region_code_alpha_3 in sub_regions[country_code_alpha_3]:
for sub_region_code_alpha_3 in sub_regions[country_code_alpha_3][region_code_alpha_3]:
region = self.get_region(
region_code_alpha_3=region_code_alpha_3,
country_code_alpha_3=country_code_alpha_3,
sub_region_code_alpha_3=sub_region_code_alpha_3)
if region:
region_ids.append(region.id)
return {'id': region_ids}
def get_sub_region_ids(self, sub_regions):
sub_region_ids = []
for country_code_alpha_3 in sub_regions:
for region_code_alpha_3 in sub_regions[country_code_alpha_3]:
region_codes = sub_regions[country_code_alpha_3][region_code_alpha_3]
for sub_region_code_alpha_3 in region_codes:
region = self.get_region(
region_code_alpha_3=region_code_alpha_3,
country_code_alpha_3=country_code_alpha_3,
sub_region_code_alpha_3=sub_region_code_alpha_3)
if region:
subdivision = subdivisions.get(parent_code=region.code.upper())
if subdivision:
sub_region = Region.objects.create(
name=subdivision.name,
code=subdivisions.code,
parent_region=region,
country=region.country)
sub_region_ids.append(sub_region.id)
if sub_regions:
for country_code_alpha_3 in sub_regions:
# FRA etc.
for region_code_alpha_3 in sub_regions[country_code_alpha_3]:
# B, C, A etc.
for sub_region_code_alpha_3 in sub_regions[country_code_alpha_3][region_code_alpha_3]:
# 24, 32 etc.
# Get parent region
region = self.get_region(
region_code_alpha_3=region_code_alpha_3,
country_code_alpha_3=country_code_alpha_3,
sub_region_code_alpha_3=sub_region_code_alpha_3)
if region:
sub_region_qs = Region.objects.filter(parent_region__code=region.code)
if sub_region_qs.exists():
sub_region_ids.append(sub_region_qs.first().id)
else:
subdivision = subdivisions.get(code=region.code.upper())
if subdivision:
sub_region = Region.objects.get_or_create(
name=subdivision.name,
code=subdivisions.parent_code,
parent_region=region,
country=region.country)
sub_region_ids.append(sub_region.id)
return {'id': set(sub_region_ids)}
return {'id': sub_region_ids}
def get_wine_region_ids(self, wine_regions):
wine_region_ids = []
if wine_regions:
for wine_region in wine_regions:
qs = WineRegion.objects.filter(name__iexact=wine_region)
if not qs.exists():
raise serializers.ValidationError({
'detail': f'Wine region - {wine_region}, is not found.'})
wine_region_ids.append(qs.first().id)
return {'id': set(wine_region_ids)}
def get_locale_ids(self, locales):
locale_ids = []
if locales:
for locale in [locale for locale in locales if locale]:
qs = Language.objects.filter(locale=locale)
if not qs.exists():
raise serializers.ValidationError({
'detail': f'{locale} is not found.'})
return {'id': set(locale_ids)}
# {'FRA': ['H', 'U']} REGIONS
# {'FRA': {'N': ['32']}} SUB REGIONS
def get_review_state(self, states):
review_states = []
if states:
for state in [state for state in states if state]:
if state == 'published':
review_states.append(Review.READY)
else:
review_states.append(Review.TO_INVESTIGATE)
return {'state': set(review_states)}
def get_guide(self, old_guide_id: int):
qs = Guide.objects.filter(old_id=old_guide_id)
if not qs.exists():
raise serializers.ValidationError({'detail': f'Guide with old id - '
f'{old_guide_id}, '
f'is not found.'})
return qs.first()