diff --git a/apps/location/models.py b/apps/location/models.py index 0b650bce..5b440560 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -102,6 +102,7 @@ class Address(models.Model): default='', help_text=_('Ex.: 350018')) coordinates = models.PointField( _('Coordinates'), blank=True, null=True, default=None) + old_id = models.IntegerField(null=True, blank=True, default=None) class Meta: """Meta class.""" diff --git a/apps/location/transfer_data.py b/apps/location/transfer_data.py index dca432e7..c079f97b 100644 --- a/apps/location/transfer_data.py +++ b/apps/location/transfer_data.py @@ -1,7 +1,7 @@ from django.db.models import Q, QuerySet -from transfer.serializers.location import CountrySerializer, RegionSerializer, CitySerializer -from transfer.models import Cities +from transfer.serializers.location import CountrySerializer, RegionSerializer, CitySerializer, AddressSerializer +from transfer.models import Cities, Locations from pprint import pprint @@ -89,6 +89,30 @@ def transfer_cities(): pprint(f"City serializer errors: {serialized_data.errors}") +def transfer_addresses(): + queryset = Locations.objects.raw("""SELECT locations.id, locations.zip_code, locations.longitude, + locations.latitude, locations.address, locations.city_id + FROM locations WHERE + locations.address != "" AND + locations.address IS NOT NULL AND + locations.city_id IS NOT NULL AND + locations.city_id IN (SELECT cities.id + FROM cities WHERE + region_code IS NOT NULL AND + region_code != "" AND + country_code_2 IS NOT NULL AND + country_code_2 != "")""") + + queryset = [vars(query) for query in queryset] + + serialized_data = AddressSerializer(data=queryset, many=True) + if serialized_data.is_valid(): + serialized_data.save() + else: + pprint(f"Address serializer errors: {serialized_data.errors}") + + + data_types = { "dictionaries": [ transfer_countries, @@ -96,5 +120,6 @@ data_types = { transfer_cities ], "tmp": [ + transfer_addresses ] } diff --git a/apps/transfer/models.py b/apps/transfer/models.py index f6dd2dbc..05f1e175 100644 --- a/apps/transfer/models.py +++ b/apps/transfer/models.py @@ -232,7 +232,7 @@ class CityPhotos(MigrateMixin): db_table = 'city_photos' -class Locations(models.Model): +class Locations(MigrateMixin): using = 'legacy' country_code = models.CharField(max_length=3) diff --git a/apps/transfer/serializers/location.py b/apps/transfer/serializers/location.py index 11d809ec..d4ea51cc 100644 --- a/apps/transfer/serializers/location.py +++ b/apps/transfer/serializers/location.py @@ -1,5 +1,8 @@ from rest_framework import serializers -from location.models import Country, Region, City +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): @@ -171,3 +174,95 @@ class CitySerializer(serializers.ModelSerializer): 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