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_core.models import AbstractBaseModel
|
||||
from django.db import models
|
||||
from django_core.models import AbstractBaseModel
|
||||
|
||||
|
||||
# class RegionModel(AbstractBaseModel):
|
||||
# name = models.CharField(max_length=255, unique=True)
|
||||
class RegionModel(AbstractBaseModel):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
|
||||
# class Meta:
|
||||
# verbose_name = "Region"
|
||||
# verbose_name_plural = "Regions"
|
||||
class Meta:
|
||||
verbose_name = "Region"
|
||||
verbose_name_plural = "Regions"
|
||||
|
||||
|
||||
# class DistrictModel(AbstractBaseModel):
|
||||
# name = models.CharField(max_length=255, unique=True)
|
||||
# region = models.ForeignKey(RegionModel, on_delete=models.CASCADE, related_name='districts')
|
||||
class DistrictModel(AbstractBaseModel):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
region = models.ForeignKey(RegionModel, on_delete=models.CASCADE, related_name='districts')
|
||||
|
||||
# class Meta:
|
||||
# verbose_name = "District"
|
||||
# verbose_name_plural = "Districts"
|
||||
class Meta:
|
||||
verbose_name = "District"
|
||||
verbose_name_plural = "Districts"
|
||||
|
||||
|
||||
# class VillageModel(AbstractBaseModel):
|
||||
# name = models.CharField(max_length=255, unique=True)
|
||||
# district = models.ForeignKey(DistrictModel, on_delete=models.CASCADE, related_name='villages')
|
||||
class VillageModel(AbstractBaseModel):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
district = models.ForeignKey(DistrictModel, on_delete=models.CASCADE, related_name='villages')
|
||||
|
||||
# class Meta:
|
||||
# verbose_name = "Village"
|
||||
# verbose_name_plural = "Villages"
|
||||
class Meta:
|
||||
verbose_name = "Village"
|
||||
verbose_name_plural = "Villages"
|
||||
|
||||
@@ -6,15 +6,16 @@ from core.apps.shared.models import RegionModel, VillageModel, DistrictModel
|
||||
class DistrictSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = DistrictModel
|
||||
fields = ('id', 'name', 'code', 'region')
|
||||
fields = ('id', 'name')
|
||||
|
||||
|
||||
class VillageSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = VillageModel
|
||||
fields = ('id', 'name', 'code', 'district')
|
||||
fields = ('id', 'name')
|
||||
|
||||
|
||||
class RegionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = RegionModel
|
||||
fields = ('id', 'name', 'code')
|
||||
fields = ('id', 'name')
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from .views import SettingsView
|
||||
from .views.region.region import RegionListCreateView, DistrictListCreateView, VillageListCreateView
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register("settings", SettingsView, basename="settings")
|
||||
@@ -8,4 +9,7 @@ router.register("settings", SettingsView, basename="settings")
|
||||
|
||||
urlpatterns = [
|
||||
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