gault-millau/apps/transfer/serializers/location.py
2019-10-28 10:13:01 +03:00

269 lines
8.2 KiB
Python

from rest_framework import serializers
from location.models import Country, Region, City, Address
from django.contrib.gis.geos import Point
from django.contrib.gis.geos import GEOSGeometry
import json
class CountrySerializer(serializers.ModelSerializer):
country_code_2 = serializers.CharField()
id = serializers.IntegerField()
class Meta:
model = 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 = Country.objects.get(code=validated_data['code'])
except Country.DoesNotExist:
country = 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 = 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 = Region.objects.get(old_id=validated_data['old_id'])
except Region.DoesNotExist:
region = Region.objects.create(**validated_data)
except Exception as e:
raise ValueError(f"REGION ERROR: {validated_data}: {e}")
return region
def set_code(self, data):
print(data)
if "subregion_code" in data and data["subregion_code"] is not None and data["subregion_code"].strip() != "":
try:
parent_region = Region.objects.get(code=str(data['region_code']))
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 = 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 = 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 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 = Region.objects.filter(code=data['region_code']).first()
except Region.DoesNotExist as e:
try:
region = Region.objects.filter(code=data['subregion_code']).first()
except Region.DoesNotExist as e:
raise ValueError(f"Region not found with {data}: {e}")
data['region'] = region
del(data['subregion_code'])
try:
country = Country.objects.get(code=data['country_code_2'])
except 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()
class Meta:
model = 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 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):
try:
city = City.objects.filter(old_id=data['city_id']).first()
except City.DoesNotExist as e:
raise ValueError(f"City not found with {data}: {e}")
data['city'] = city
del(data['city_id'])
return data
def set_address(self, data):
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
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