322 lines
9.9 KiB
Python
322 lines
9.9 KiB
Python
from rest_framework import serializers
|
|
from location.models import Country, Region, City, Address
|
|
from django.contrib.gis.geos import Point
|
|
from django.core.exceptions import MultipleObjectsReturned
|
|
|
|
|
|
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):
|
|
if "subregion_code" in data and data["subregion_code"] is not None and data["subregion_code"].strip() != "":
|
|
try:
|
|
parent_region = 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 = 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
|
|
|
|
|
|
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 = 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 = City.objects.get(old_id=data['old_id'])
|
|
except 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
|