378 lines
11 KiB
Python
378 lines
11 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 tag.models import TagCategory
|
|
from django.utils.text import slugify
|
|
|
|
|
|
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):
|
|
print(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()
|
|
|
|
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):
|
|
try:
|
|
city = models.City.objects.filter(old_id=data['city_id']).first()
|
|
except models.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 WineRegion(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 WineSubRegion(WineRegion):
|
|
|
|
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 WineVillage(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 CepageWineRegionsSerializer(TransferSerializerMixin):
|
|
|
|
cepage_id = serializers.PrimaryKeyRelatedField(
|
|
queryset=Cepages.objects.all())
|
|
wine_region_id = serializers.IntegerField()
|
|
|
|
class Meta(WineRegion.Meta):
|
|
fields = [
|
|
'cepage_id',
|
|
'wine_region_id',
|
|
]
|
|
|
|
def create(self, validated_data):
|
|
obj = self.get_wine_region(validated_data['wine_region_id'])
|
|
tag_category = self.get_tag_category(validated_data['cepage_id'])
|
|
|
|
if obj and tag_category not in obj.tag_categories.all():
|
|
obj.tag_categories.add(tag_category)
|
|
return obj
|
|
|
|
def get_tag_category(self, tag_category):
|
|
if isinstance(tag_category, Cepages):
|
|
tag_category = tag_category.name
|
|
qs = TagCategory.objects.filter(index_name=slugify(tag_category))
|
|
if qs.exists():
|
|
return qs.first()
|