fix
This commit is contained in:
144
core/apps/shared/management/commands/save_regions.py
Normal file
144
core/apps/shared/management/commands/save_regions.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
from core.apps.shared.models import RegionModel, DistrictModel, VillageModel
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Import regions, districts, and neighborhoods from JSON files."
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument('--path', type=str, default='JSON/', help='Path to JSON files directory')
|
||||||
|
|
||||||
|
def transliterate_uz_to_en(self, text):
|
||||||
|
"""Simple transliteration for English names"""
|
||||||
|
if not text:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
mapping = {
|
||||||
|
"o'": "o", "O'": "O",
|
||||||
|
"g'": "g", "G'": "G",
|
||||||
|
"sh": "sh", "Sh": "Sh",
|
||||||
|
"ch": "ch", "Ch": "Ch",
|
||||||
|
"ng": "ng", "Ng": "Ng",
|
||||||
|
"q": "q", "Q": "Q",
|
||||||
|
"yo": "yo", "Yo": "Yo",
|
||||||
|
"yu": "yu", "Yu": "Yu",
|
||||||
|
"ya": "ya", "Ya": "Ya",
|
||||||
|
"ye": "ye", "Ye": "Ye",
|
||||||
|
"o‘": "o", "O‘": "O",
|
||||||
|
"g‘": "g", "G‘": "G",
|
||||||
|
}
|
||||||
|
|
||||||
|
res = text
|
||||||
|
for k, v in mapping.items():
|
||||||
|
res = res.replace(k, v)
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
"viloyati": "Region",
|
||||||
|
"viloyat": "Region",
|
||||||
|
"tumani": "District",
|
||||||
|
"tuman": "District",
|
||||||
|
"shahri": "City",
|
||||||
|
"shahar": "City",
|
||||||
|
"Respublikasi": "Republic",
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v in replacements.items():
|
||||||
|
res = res.replace(k, v)
|
||||||
|
res = res.replace(k.capitalize(), v)
|
||||||
|
|
||||||
|
return res.strip()
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
path = options['path']
|
||||||
|
|
||||||
|
regions_file = os.path.join(path, 'regions.json')
|
||||||
|
districts_file = os.path.join(path, 'districts.json')
|
||||||
|
villages_file = os.path.join(path, 'villages.json')
|
||||||
|
|
||||||
|
try:
|
||||||
|
with transaction.atomic():
|
||||||
|
# 1. Import Regions
|
||||||
|
self.stdout.write("Importing Regions...")
|
||||||
|
if os.path.exists(regions_file):
|
||||||
|
with open(regions_file, 'r', encoding='utf-8-sig') as f:
|
||||||
|
regions_data = json.load(f)
|
||||||
|
for item in regions_data:
|
||||||
|
name_uz = item.get('name_uz', '')
|
||||||
|
name_ru = item.get('name_ru', '') or name_uz
|
||||||
|
name_en = self.transliterate_uz_to_en(name_uz)
|
||||||
|
|
||||||
|
# Use get_or_create to avoid duplicates if ID matches or name matches
|
||||||
|
# Actually, it's better to use our own internal IDs if we want to link them
|
||||||
|
# But since many JSON files use these IDs, we'll store them as a reference or use them directly if we reset the DB
|
||||||
|
region, created = RegionModel.objects.update_or_create(
|
||||||
|
id=item['id'],
|
||||||
|
defaults={
|
||||||
|
'name_uz': name_uz,
|
||||||
|
'name_ru': name_ru,
|
||||||
|
'name_en': name_en,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. Import Districts
|
||||||
|
self.stdout.write("Importing Districts...")
|
||||||
|
if os.path.exists(districts_file):
|
||||||
|
with open(districts_file, 'r', encoding='utf-8-sig') as f:
|
||||||
|
districts_data = json.load(f)
|
||||||
|
for item in districts_data:
|
||||||
|
name_uz = item.get('name_uz', '')
|
||||||
|
name_ru = item.get('name_ru', '') or name_uz
|
||||||
|
name_en = self.transliterate_uz_to_en(name_uz)
|
||||||
|
|
||||||
|
region_id = item.get('region_id')
|
||||||
|
if not RegionModel.objects.filter(id=region_id).exists():
|
||||||
|
self.stdout.write(self.style.WARNING(f"Region {region_id} not found for district {name_uz}"))
|
||||||
|
continue
|
||||||
|
|
||||||
|
DistrictModel.objects.update_or_create(
|
||||||
|
id=item['id'],
|
||||||
|
defaults={
|
||||||
|
'region_id': region_id,
|
||||||
|
'name_uz': name_uz,
|
||||||
|
'name_ru': name_ru,
|
||||||
|
'name_en': name_en,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. Import Neighborhoods (Villages)
|
||||||
|
self.stdout.write("Importing Neighborhoods (Villages)...")
|
||||||
|
if os.path.exists(villages_file):
|
||||||
|
with open(villages_file, 'r', encoding='utf-8-sig') as f:
|
||||||
|
villages_data = json.load(f)
|
||||||
|
count = 0
|
||||||
|
total = len(villages_data)
|
||||||
|
for item in villages_data:
|
||||||
|
name_uz = item.get('name_uz', '')
|
||||||
|
name_ru = item.get('name_ru', '') or name_uz
|
||||||
|
name_en = self.transliterate_uz_to_en(name_uz)
|
||||||
|
|
||||||
|
district_id = item.get('district_id')
|
||||||
|
if not DistrictModel.objects.filter(id=district_id).exists():
|
||||||
|
continue
|
||||||
|
|
||||||
|
NeighborhoodModel.objects.update_or_create(
|
||||||
|
id=item['id'],
|
||||||
|
defaults={
|
||||||
|
'district_id': district_id,
|
||||||
|
'name_uz': name_uz,
|
||||||
|
'name_ru': name_ru,
|
||||||
|
'name_en': name_en,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
count += 1
|
||||||
|
if count % 1000 == 0:
|
||||||
|
self.stdout.write(f"Processed {count}/{total} neighborhoods...")
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS("Import completed successfully!"))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(self.style.ERROR(f"Error: {str(e)}"))
|
||||||
@@ -1,28 +1,28 @@
|
|||||||
# from django.db import models
|
from django.db import models
|
||||||
# from django_core.models import AbstractBaseModel
|
from django_core.models import AbstractBaseModel
|
||||||
|
|
||||||
|
|
||||||
# class RegionModel(AbstractBaseModel):
|
class RegionModel(AbstractBaseModel):
|
||||||
# name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255, unique=True)
|
||||||
|
|
||||||
# class Meta:
|
class Meta:
|
||||||
# verbose_name = "Region"
|
verbose_name = "Region"
|
||||||
# verbose_name_plural = "Regions"
|
verbose_name_plural = "Regions"
|
||||||
|
|
||||||
|
|
||||||
# class DistrictModel(AbstractBaseModel):
|
class DistrictModel(AbstractBaseModel):
|
||||||
# name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255, unique=True)
|
||||||
# region = models.ForeignKey(RegionModel, on_delete=models.CASCADE, related_name='districts')
|
region = models.ForeignKey(RegionModel, on_delete=models.CASCADE, related_name='districts')
|
||||||
|
|
||||||
# class Meta:
|
class Meta:
|
||||||
# verbose_name = "District"
|
verbose_name = "District"
|
||||||
# verbose_name_plural = "Districts"
|
verbose_name_plural = "Districts"
|
||||||
|
|
||||||
|
|
||||||
# class VillageModel(AbstractBaseModel):
|
class VillageModel(AbstractBaseModel):
|
||||||
# name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255, unique=True)
|
||||||
# district = models.ForeignKey(DistrictModel, on_delete=models.CASCADE, related_name='villages')
|
district = models.ForeignKey(DistrictModel, on_delete=models.CASCADE, related_name='villages')
|
||||||
|
|
||||||
# class Meta:
|
class Meta:
|
||||||
# verbose_name = "Village"
|
verbose_name = "Village"
|
||||||
# verbose_name_plural = "Villages"
|
verbose_name_plural = "Villages"
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ from core.apps.shared.models import RegionModel, VillageModel, DistrictModel
|
|||||||
class DistrictSerializer(serializers.ModelSerializer):
|
class DistrictSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = DistrictModel
|
model = DistrictModel
|
||||||
fields = ('id', 'name', 'code', 'region')
|
fields = ('id', 'name')
|
||||||
|
|
||||||
|
|
||||||
class VillageSerializer(serializers.ModelSerializer):
|
class VillageSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VillageModel
|
model = VillageModel
|
||||||
fields = ('id', 'name', 'code', 'district')
|
fields = ('id', 'name')
|
||||||
|
|
||||||
|
|
||||||
class RegionSerializer(serializers.ModelSerializer):
|
class RegionSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RegionModel
|
model = RegionModel
|
||||||
fields = ('id', 'name', 'code')
|
fields = ('id', 'name')
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from .views import SettingsView
|
from .views import SettingsView
|
||||||
|
from .views.region.region import RegionListCreateView, DistrictListCreateView, VillageListCreateView
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register("settings", SettingsView, basename="settings")
|
router.register("settings", SettingsView, basename="settings")
|
||||||
@@ -8,4 +9,7 @@ router.register("settings", SettingsView, basename="settings")
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", include(router.urls)),
|
path("", include(router.urls)),
|
||||||
|
path("region/", RegionListCreateView.as_view(), name="region-list-create"),
|
||||||
|
path("district/", DistrictListCreateView.as_view(), name="district-list-create"),
|
||||||
|
path("village/", VillageListCreateView.as_view(), name="village-list-create"),
|
||||||
]
|
]
|
||||||
|
|||||||
41
core/apps/shared/views/region/region.py
Normal file
41
core/apps/shared/views/region/region.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
from rest_framework import generics
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
|
from core.apps.shared.serializers.region.district import DistrictSerializer, VillageSerializer, RegionSerializer
|
||||||
|
from core.apps.shared.models import RegionModel, VillageModel, DistrictModel
|
||||||
|
|
||||||
|
|
||||||
|
class DistrictListCreateView(generics.ListCreateAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
serializer_class = DistrictSerializer
|
||||||
|
queryset = DistrictModel.objects.all()
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
region = self.request.query_params.get('region')
|
||||||
|
name = self.request.query_params.get('name')
|
||||||
|
if name:
|
||||||
|
return self.queryset.filter(name__icontains=name)
|
||||||
|
if region:
|
||||||
|
return self.queryset.filter(region=region)
|
||||||
|
return super().get_queryset()
|
||||||
|
|
||||||
|
|
||||||
|
class VillageListCreateView(generics.ListCreateAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
serializer_class = VillageSerializer
|
||||||
|
queryset = VillageModel.objects.all()
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
district = self.request.query_params.get('district')
|
||||||
|
name = self.request.query_params.get('name')
|
||||||
|
if district:
|
||||||
|
return self.queryset.filter(district=district)
|
||||||
|
if name:
|
||||||
|
return self.queryset.filter(name__icontains=name)
|
||||||
|
return super().get_queryset()
|
||||||
|
|
||||||
|
|
||||||
|
class RegionListCreateView(generics.ListCreateAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
serializer_class = RegionSerializer
|
||||||
|
queryset = RegionModel.objects.all()
|
||||||
1682
resources/json/district.json
Normal file
1682
resources/json/district.json
Normal file
File diff suppressed because it is too large
Load Diff
100
resources/json/region.json
Normal file
100
resources/json/region.json
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"soato_id": 1703,
|
||||||
|
"name_uz": "Andijon viloyati",
|
||||||
|
"name_oz": "Андижон вилояти",
|
||||||
|
"name_ru": "Андижанская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"soato_id": 1706,
|
||||||
|
"name_uz": "Buxoro viloyati",
|
||||||
|
"name_oz": "Бухоро вилояти",
|
||||||
|
"name_ru": "Бухарская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"soato_id": 1708,
|
||||||
|
"name_uz": "Jizzax viloyati",
|
||||||
|
"name_oz": "Жиззах вилояти",
|
||||||
|
"name_ru": "Джизакская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"soato_id": 1710,
|
||||||
|
"name_uz": "Qashqadaryo viloyati",
|
||||||
|
"name_oz": "Қашқадарё вилояти",
|
||||||
|
"name_ru": "Кашкадарьинская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"soato_id": 1712,
|
||||||
|
"name_uz": "Navoiy viloyati",
|
||||||
|
"name_oz": "Навоий вилояти",
|
||||||
|
"name_ru": "Навоийская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"soato_id": 1714,
|
||||||
|
"name_uz": "Namangan viloyati",
|
||||||
|
"name_oz": "Наманган вилояти",
|
||||||
|
"name_ru": "Наманганская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"soato_id": 1718,
|
||||||
|
"name_uz": "Samarqand viloyati",
|
||||||
|
"name_oz": "Самарқанд вилояти",
|
||||||
|
"name_ru": "Самаркандская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"soato_id": 1724,
|
||||||
|
"name_uz": "Sirdaryo viloyati",
|
||||||
|
"name_oz": "Сирдарё вилояти",
|
||||||
|
"name_ru": "Сырдарьинская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"soato_id": 1726,
|
||||||
|
"name_uz": "Toshkent shahri",
|
||||||
|
"name_oz": "Тошкент шаҳри",
|
||||||
|
"name_ru": "город Ташкент"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"soato_id": 1727,
|
||||||
|
"name_uz": "Toshkent viloyati",
|
||||||
|
"name_oz": "Тошкент вилояти",
|
||||||
|
"name_ru": "Ташкентская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"soato_id": 1730,
|
||||||
|
"name_uz": "Farg'ona viloyati",
|
||||||
|
"name_oz": "Фарғона вилояти",
|
||||||
|
"name_ru": "Ферганская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 14,
|
||||||
|
"soato_id": 1733,
|
||||||
|
"name_uz": "Xorazm viloyati",
|
||||||
|
"name_oz": "Хоразм вилояти",
|
||||||
|
"name_ru": "Хорезмская область"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 15,
|
||||||
|
"soato_id": 1735,
|
||||||
|
"name_uz": "Qoraqalpog'iston Respublikasi",
|
||||||
|
"name_oz": "Қорақалпоғистон Республикаси",
|
||||||
|
"name_ru": "Республика Каракалпакстан"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5723,
|
||||||
|
"soato_id": 1722,
|
||||||
|
"name_uz": "Surxondaryo viloyati",
|
||||||
|
"name_oz": "Сурхондарё вилояти",
|
||||||
|
"name_ru": "Сурхандарьинская область"
|
||||||
|
}
|
||||||
|
]
|
||||||
21130
resources/json/village.json
Normal file
21130
resources/json/village.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user