450 lines
14 KiB
Python
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
|