gault-millau/apps/transfer/serializers/location.py
2020-02-03 16:57:00 +03:00

450 lines
14 KiB
Python

from django.conf import settings
from django.contrib.gis.geos import Point
from rest_framework import serializers
from location import models
from transfer.mixins import TransferSerializerMixin
from utils.methods import get_point_from_coordinates
from transfer.models import Cepages
from django.utils.text import slugify
from django.contrib.gis.geos import Point
from django.core.exceptions import MultipleObjectsReturned
from gallery.models import Image
class CountrySerializer(serializers.ModelSerializer):
country_code_2 = serializers.CharField()
id = serializers.IntegerField()
class Meta:
model = models.Country
fields = (
"id",
"country_code_2",
)
def validate(self, data):
data["code"] = self.get_country_code(data)
del (data['country_code_2'])
data['old_id'] = data.pop('id')
return data
def create(self, validated_data):
# Some countries already in database
try:
country = models.Country.objects.get(code=validated_data['code'])
except models.Country.DoesNotExist:
country = models.Country.objects.create(**validated_data)
return country
def get_country_code(self, obj):
return obj.get("country_code_2")
class RegionSerializer(serializers.ModelSerializer):
region_code = serializers.CharField()
subregion_code = serializers.CharField(allow_null=True, allow_blank=True)
country_code_2 = serializers.CharField()
id = serializers.IntegerField()
class Meta:
model = models.Region
fields = (
"region_code",
"country_code_2",
"subregion_code",
"id"
)
def validate(self, data):
data = self.set_old_id(data)
data = self.set_code(data)
data = self.set_country(data)
return data
def create(self, validated_data):
# Some regions may be already in database
try:
region = models.Region.objects.get(old_id=validated_data['old_id'])
except models.Region.DoesNotExist:
region = models.Region.objects.create(**validated_data)
except Exception as e:
raise ValueError(f"REGION ERROR: {validated_data}: {e}")
return region
def set_code(self, data):
if "subregion_code" in data and data["subregion_code"] is not None and data["subregion_code"].strip() != "":
try:
parent_region = models.Region.objects.filter(code=str(data['region_code'])).first()
except Exception as e:
raise ValueError(f"Parent region error with {data}: {e}")
data['parent_region'] = parent_region
data['code'] = data.pop('subregion_code')
del (data['region_code'])
else:
data['code'] = data.pop('region_code')
del (data['subregion_code'])
return data
def set_country(self, data):
try:
country = models.Country.objects.get(code=data['country_code_2'])
except Exception as e:
raise ValueError(f"Country error with {data}: {e}")
data["country"] = country
del (data['country_code_2'])
return data
def set_old_id(self, data):
data['old_id'] = data.pop("id")
return data
class CitySerializer(serializers.ModelSerializer):
country_code_2 = serializers.CharField()
region_code = serializers.CharField()
subregion_code = serializers.CharField(allow_null=True, allow_blank=True)
zip_code = serializers.CharField(allow_null=True, allow_blank=True)
is_island = serializers.IntegerField(allow_null=True)
name = serializers.CharField()
id = serializers.IntegerField()
class Meta:
model = models.City
fields = (
"country_code_2",
"region_code",
"subregion_code",
"zip_code",
"is_island",
"name",
"id"
)
def validate(self, data):
data = self.set_old_id(data)
data = self.set_relations(data)
data = self.set_is_island(data)
data = self.set_code(data)
data = self.set_zip_code(data)
return data
def create(self, validated_data):
return models.City.objects.create(**validated_data)
def set_is_island(self, data):
data['is_island'] = True if "is_island" in data \
and data['is_island'] is not None \
and data['is_island'] > 0 \
else False
return data
def set_code(self, data):
data['code'] = data.pop('region_code')
return data
def set_relations(self, data):
try:
region = models.Region.objects.filter(code=data['region_code']).first()
except models.Region.DoesNotExist as e:
try:
region = models.Region.objects.filter(code=data['subregion_code']).first()
except models.Region.DoesNotExist as e:
raise ValueError(f"Region not found with {data}: {e}")
data['region'] = region
del (data['subregion_code'])
try:
country = models.Country.objects.get(code=data['country_code_2'])
except models.Country.DoesNotExist as e:
raise ValueError(f"Country not found with {data}: {e}")
data['country'] = country
del (data['country_code_2'])
return data
def set_zip_code(self, data):
data['postal_code'] = data.pop('zip_code')
if data['postal_code'] is None:
data['postal_code'] = ""
return data
def set_old_id(self, data):
data['old_id'] = data.pop('id')
return data
class AddressSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
city_id = serializers.IntegerField()
zip_code = serializers.CharField(allow_null=True, allow_blank=True)
latitude = serializers.DecimalField(max_digits=10, decimal_places=6, allow_null=True)
longitude = serializers.DecimalField(max_digits=10, decimal_places=6, allow_null=True)
address = serializers.CharField(allow_null=True, allow_blank=True)
class Meta:
model = models.Address
fields = (
"id",
"city_id",
"zip_code",
"latitude",
"longitude",
"address"
)
def validate(self, data):
data = self.set_old_id(data)
data = self.set_address(data)
data = self.set_postal_code(data)
data = self.set_city(data)
data = self.set_point(data)
return data
def create(self, validated_data):
return models.Address.objects.create(**validated_data)
def set_old_id(self, data):
data['old_id'] = data.pop("id")
return data
def set_postal_code(self, data):
data['postal_code'] = data.pop('zip_code', None)
if data['postal_code'] is None:
data['postal_code'] = ""
return data
def set_city(self, data):
city = models.City.objects.filter(mysql_id=data['city_id']).first()
if not city:
raise ValueError(f"City not found with ID {data['city_id']}")
data['city_id'] = city.id
return data
def set_address(self, data):
if "address" in data and data['address'] is not None and data['address'] != "":
address_list = data.pop('address').split(' ')
is_first_street = False
data['street_name_1'] = []
data['street_name_2'] = []
while len(address_list) > 0:
address_part = address_list.pop()
try:
address_part = int(address_part)
data['number'] = address_part
is_first_street = True
except:
if is_first_street:
data['street_name_1'].append(address_part)
else:
data['street_name_2'].append(address_part)
data['street_name_1'] = " ".join(data['street_name_1'])
data['street_name_2'] = " ".join(data['street_name_2'])
if "number" not in data:
data['number'] = 0
else:
del (data['address'])
data['number'] = 0
return data
def set_point(self, data):
if data['latitude'] is not None and data['longitude'] is not None:
data['coordinates'] = Point(float(data['longitude']), float(data['latitude']))
# data['coordinates'] = GEOSGeometry(
# json.dumps({
# "type": "Point",
# "coordinates": [data['longitude'], data['latitude']]
# }, ensure_ascii=False, default=str)
# )
else:
data['coordinates'] = None
del (data['latitude'])
del (data['longitude'])
return data
class WineRegionSerializer(TransferSerializerMixin):
id = serializers.IntegerField()
name = serializers.CharField()
desc = serializers.CharField(allow_null=True)
latitude = serializers.FloatField(allow_null=True)
longitude = serializers.FloatField(allow_null=True)
class Meta:
model = models.WineRegion
fields = (
'id',
'name',
'desc',
'latitude',
'longitude',
)
def validate(self, attrs):
latitude = attrs.pop('latitude', None)
longitude = attrs.pop('longitude', None)
attrs['old_id'] = attrs.pop('id')
attrs['description'] = {settings.FALLBACK_LOCALE: attrs.pop('desc', None)}
attrs['coordinates'] = get_point_from_coordinates(latitude, longitude)
return attrs
class WineSubRegionSerializer(WineRegionSerializer):
id = serializers.IntegerField()
name = serializers.CharField()
parent_id = serializers.IntegerField()
class Meta:
model = models.WineSubRegion
fields = (
'id',
'name',
'parent_id',
)
def validate(self, attrs):
parent_id = attrs.pop('parent_id', None)
attrs['old_id'] = attrs.pop('id')
attrs['wine_region'] = self.get_wine_region(parent_id)
return attrs
def get_wine_region(self, parent_id):
qs = models.WineRegion.objects.filter(old_id=parent_id)
if qs.exists():
return qs.first()
class WineVillageSerializer(TransferSerializerMixin):
id = serializers.IntegerField()
name = serializers.CharField()
parent_id = serializers.IntegerField()
class Meta:
model = models.WineVillage
fields = (
'id',
'name',
'parent_id',
)
def validate(self, attrs):
parent_id = attrs.pop('parent_id', None)
attrs['old_id'] = attrs.pop('id')
attrs['wine_region'] = self.get_wine_region(parent_id)
return attrs
class CityMapSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
map1 = serializers.CharField(allow_blank=True, allow_null=True)
map2 = serializers.CharField(allow_blank=True, allow_null=True)
map_ref = serializers.CharField(allow_blank=True, allow_null=True)
situation = serializers.CharField(allow_blank=True, allow_null=True)
class Meta:
model = models.City
fields = (
"id",
"map1",
"map2",
"map_ref",
"situation",
)
def validate(self, data):
data = self.set_old_id(data)
data = self.set_city(data)
data = self.set_null_fields(data)
return data
def create(self, validated_data):
city = validated_data.pop('city')
city.update(
map1=validated_data['map1'],
map2=validated_data['map2'],
map_ref=validated_data['map_ref'],
situation=validated_data['situation']
)
def set_old_id(self, data):
data['old_id'] = data.pop("id")
return data
def set_city(self, data):
try:
city = models.City.objects.get(old_id=data['old_id'])
except models.City.DoesNotExist as e:
raise ValueError(f"Cannot find city with id = {data['old_id']}: {e}")
except MultipleObjectsReturned as e:
raise ValueError(f"Find multiple cities with id = {data['old_id']}: {e}")
data['city'] = city
return data
def set_null_fields(self, data):
for field in ["map1", "map2", "map_ref", "situation"]:
if field not in data or data[field] is None:
data[field] = ""
return data
class CityMapCorrectSerializer(CityMapSerializer):
def set_city(self, data):
try:
city = models.City.objects.get(mysql_id=data['old_id'])
except models.City.DoesNotExist as e:
raise ValueError(f"Cannot find city with id = {data['old_id']}: {e}")
except MultipleObjectsReturned as e:
raise ValueError(f"Find multiple cities with id = {data['old_id']}: {e}")
data['city'] = city
return data
def create(self, validated_data):
city = validated_data.pop('city')
city.map1 = validated_data['map1'],
city.map2 = validated_data['map2'],
city.map_ref = validated_data['map_ref'],
city.situation = validated_data['situation']
city.save()
class CepageWineRegionSerializer(TransferSerializerMixin):
CATEGORY_LABEL = 'Cepage'
CATEGORY_INDEX_NAME = slugify(CATEGORY_LABEL)
cepage_id = serializers.PrimaryKeyRelatedField(
queryset=Cepages.objects.all())
wine_region_id = serializers.IntegerField()
class Meta(WineRegionSerializer.Meta):
fields = [
'cepage_id',
'wine_region_id',
]
def create(self, validated_data):
obj = self.get_wine_region(validated_data['wine_region_id'])
cepage = validated_data.get('cepage_id')
tag = self.get_tag(cepage.name, self.CATEGORY_INDEX_NAME)
if obj and tag not in obj.tags.all():
obj.tags.add(tag)
return obj