from rest_framework import serializers from location.models import Country, Region, City 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.DoesNotExists: 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) country_code_2 = serializers.CharField() class Meta: model = Region fields = ( "region_code", "country_code_2", "subregion_code" ) def validate(self, data): if "subregion" in data and data["subregion"] is not None: 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'] = str(data.pop('subregion_code')) else: data['code'] = str(data.pop('region_code')) 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']) del(data['subregion_code']) return data def create(self, validated_data): # Some regions may be already in database try: region, _ = Region.objects.get_or_create(**validated_data) except Exception as e: raise ValueError(f"{validated_data}: {e}") return region class CitySerializer(serializers.ModelSerializer): country_code_2 = serializers.CharField() subregion_code = serializers.CharField() zip_code = serializers.CharField() is_island = serializers.IntegerField() name = serializers.CharField() class Meta: model = City fields = ( "country_code_2", "subregion_code", "zip_code", "is_island", "name", ) def validate(self, data): data = self.set_is_island(data) data = self.set_code(data) data = self.set_zip_code(data) data = self.set_relations(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('country_code_2') return data def set_relations(self, data): try: region = Region.objects.get(code=data['code']) except: try: region = Region.objects.get(code=data['subregion_code']) except Exception 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['code']) except Exception as e: raise ValueError(f"Region not found with {data}: {e}") data['country'] = country return data def set_zip_code(self, data): data['postal_code'] = data.pop('zip_code') return data