categorylanri import qilish qoshildi

This commit is contained in:
Husanjonazamov
2026-03-26 14:23:51 +05:00
parent 1c4155299d
commit 73ae84768f
5 changed files with 149 additions and 3 deletions

View File

@@ -0,0 +1,145 @@
import json
import os
import re
from pathlib import Path
from django.core.management.base import BaseCommand
from django.core.files import File
from django.conf import settings
from django.db import transaction
from core.apps.api.models import FilialModel, CategoryModel, SubcategoryModel, ProductsModel, SubProductModel
class Command(BaseCommand):
help = 'Import restaurants and products from JSON assets'
def handle(self, *args, **options):
base_dir = Path(settings.BASE_DIR)
json_dir = base_dir / 'assets' / 'json'
images_dir = base_dir / 'assets' / 'images'
product_map = {} # Maps (filial_name, item_id) to ProductsModel instance
# 1. Process Main Food Containers
food_container_files = sorted(json_dir.glob('FoodContainer*.json'))
for file_path in food_container_files:
file_name = file_path.name
# Extract Filial name: FoodContainerKaromat20.json -> Karomat
match = re.search(r'FoodContainer([A-Za-z]+)(\d+)?\.json', file_name)
if not match:
self.stdout.write(self.style.WARNING(f"Skipping {file_name}, regex mismatch"))
continue
filial_name = match.group(1)
if not filial_name:
filial_name = "Default"
self.stdout.write(self.style.SUCCESS(f"Processing filial: {filial_name} from {file_name}"))
# Filial can be shared across multiple JSON files
filial, _ = FilialModel.objects.get_or_create(name=filial_name)
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
current_category = None
current_subcategory = None
with transaction.atomic():
for item in data:
is_header = item.get('isHeader') == 1
name = item.get('nameRu') or item.get('nameEn') or "Unnamed"
price = item.get('price', 0)
image_name = item.get('image')
json_id = item.get('id')
if is_header:
# Create Category and Subcategory
current_category, created = CategoryModel.objects.get_or_create(
filial=filial,
name=name
)
if created and image_name:
self.attach_image(current_category, image_name, images_dir)
current_subcategory, created = SubcategoryModel.objects.get_or_create(
category=current_category,
name=name
)
self.stdout.write(f" Category/Subcategory: {name}")
else:
if not current_subcategory:
# Fallback if no header found yet
cat_name = "General"
current_category, _ = CategoryModel.objects.get_or_create(
filial=filial,
name=cat_name
)
current_subcategory, _ = SubcategoryModel.objects.get_or_create(
category=current_category,
name=cat_name
)
# Create Product
# We use get_or_create with name and subcategory to avoid obvious duplicates
product, created = ProductsModel.objects.get_or_create(
name=name,
subcategory=current_subcategory,
defaults={'price': price if price > 0 else 0}
)
if created:
if image_name:
self.attach_image(product, image_name, images_dir)
self.stdout.write(f" Added Product: {name}")
# Store in map (scoped by filial and ID) for subproduct linking
product_map[(filial_name, json_id)] = product
# 2. Process Food Detail Containers (Subproducts)
food_detail_files = sorted(json_dir.glob('FoodDetailContainer*.json'))
for file_path in food_detail_files:
file_name = file_path.name
match = re.search(r'FoodDetailContainer(.*?)(?:\d+)?\.json', file_name)
if not match:
continue
filial_name = match.group(1)
self.stdout.write(self.style.SUCCESS(f"Processing subproducts for filial: {filial_name} from {file_name}"))
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
with transaction.atomic():
for item in data:
food_id = item.get('foodId')
name = item.get('nameEn') or item.get('nameRu') or "Unnamed Subproduct"
price = item.get('price', 0)
product_key = (filial_name, food_id)
if product_key in product_map:
parent_product = product_map[product_key]
sub_product, created = SubProductModel.objects.get_or_create(
product=parent_product,
name=name,
defaults={'price': price if price > 0 else 0}
)
if created:
self.stdout.write(f" Added SubProduct: {name} for {parent_product.name}")
else:
# Sometimes subproducts might refer to products from other files or just missing
pass
def attach_image(self, instance, image_name, images_dir):
# Try different extensions
if not image_name:
return False
for ext in ['.jpg', '.png', '.jpeg', '.webp']:
img_path = images_dir / (image_name + ext)
if img_path.exists():
try:
with open(img_path, 'rb') as img_file:
instance.image.save(img_path.name, File(img_file), save=True)
return True
except Exception as e:
self.stdout.write(self.style.ERROR(f" Error saving image {image_name}: {e}"))
return False