xavfsizlik taminlandi
This commit is contained in:
@@ -13,124 +13,87 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
base_dir = Path(settings.BASE_DIR)
|
base_dir = Path(settings.BASE_DIR)
|
||||||
json_dir = base_dir / 'assets' / 'json'
|
full_json_path = base_dir / 'assets' / 'menu_full.json'
|
||||||
images_dir = base_dir / 'assets' / 'images'
|
images_dir = base_dir / 'assets' / 'images'
|
||||||
|
|
||||||
|
if not full_json_path.exists():
|
||||||
|
self.stdout.write(self.style.ERROR(f"File not found: {full_json_path}"))
|
||||||
|
return
|
||||||
|
|
||||||
# 0. Clear Database
|
# 0. Clear Database
|
||||||
self.stdout.write(self.style.WARNING("Clearing existing data..."))
|
self.stdout.write(self.style.WARNING("Clearing existing data..."))
|
||||||
FilialModel.objects.all().delete()
|
FilialModel.objects.all().delete()
|
||||||
|
|
||||||
product_map = {} # Maps (filial_name, item_id) to ProductsModel instance
|
with open(full_json_path, 'r', encoding='utf-8') as f:
|
||||||
|
full_data = json.load(f)
|
||||||
|
|
||||||
# 1. Process Main Food Containers
|
# 1. Process Hierarchy
|
||||||
food_container_files = sorted(json_dir.glob('FoodContainer*.json'))
|
# Root is a dict of filials: {"karomat": {...}, "qoratosh": {...}}
|
||||||
|
for filial_slug, sections in full_data.items():
|
||||||
for file_path in food_container_files:
|
filial_name = filial_slug.capitalize()
|
||||||
file_name = file_path.name
|
self.stdout.write(self.style.SUCCESS(f"Processing Filial: {filial_name}"))
|
||||||
# Extract Filial name and Type ID: FoodContainerKaromat15.json -> Karomat, 15
|
|
||||||
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) or "Default"
|
|
||||||
type_id = match.group(2)
|
|
||||||
|
|
||||||
# Determine Category by Filename ID (15=Restaurant, 20=Bar)
|
|
||||||
if type_id == '15':
|
|
||||||
cat_name = "Restaurant"
|
|
||||||
cat_type = CategoryModel.CategoryType.RESTAURANT
|
|
||||||
elif type_id == '20':
|
|
||||||
cat_name = "Bar"
|
|
||||||
cat_type = CategoryModel.CategoryType.BAR
|
|
||||||
else:
|
|
||||||
cat_name = f"Category {type_id}"
|
|
||||||
cat_type = CategoryModel.CategoryType.RESTAURANT
|
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f"Processing Filial: {filial_name}, Category: {cat_name} from {file_name}"))
|
|
||||||
|
|
||||||
filial, _ = FilialModel.objects.get_or_create(name=filial_name)
|
filial, _ = FilialModel.objects.get_or_create(name=filial_name)
|
||||||
category, _ = CategoryModel.objects.get_or_create(
|
|
||||||
filial=filial,
|
|
||||||
name=cat_name,
|
|
||||||
defaults={'type': cat_type}
|
|
||||||
)
|
|
||||||
|
|
||||||
with open(file_path, 'r', encoding='utf-8') as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
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:
|
# Sections are "restoran" and "bar"
|
||||||
# Headers are Subcategories
|
for section_slug, groups in sections.items():
|
||||||
current_subcategory, created = SubcategoryModel.objects.get_or_create(
|
cat_name = section_slug.capitalize() # "Restoran" or "Bar"
|
||||||
|
cat_type = CategoryModel.CategoryType.RESTAURANT
|
||||||
|
if section_slug.lower() == 'bar':
|
||||||
|
cat_type = CategoryModel.CategoryType.BAR
|
||||||
|
|
||||||
|
category, _ = CategoryModel.objects.get_or_create(
|
||||||
|
filial=filial,
|
||||||
|
name=cat_name,
|
||||||
|
defaults={'type': cat_type}
|
||||||
|
)
|
||||||
|
self.stdout.write(f" Category({cat_type}): {cat_name}")
|
||||||
|
|
||||||
|
# Groups are items in the list (e.g. Salads, Soups)
|
||||||
|
for group in groups:
|
||||||
|
type_name = group.get('typeName', 'General')
|
||||||
|
|
||||||
|
# group has "subCategories"
|
||||||
|
for subcat_data in group.get('subCategories', []):
|
||||||
|
subcat_name = subcat_data.get('name', 'General')
|
||||||
|
|
||||||
|
# Use group's type_name if subcat_name is a placeholder (starts with '(')
|
||||||
|
if subcat_name.startswith('('):
|
||||||
|
subcat_name = type_name
|
||||||
|
|
||||||
|
subcategory, created = SubcategoryModel.objects.get_or_create(
|
||||||
category=category,
|
category=category,
|
||||||
name=name
|
name=subcat_name
|
||||||
)
|
)
|
||||||
if created and image_name:
|
|
||||||
self.attach_image(current_subcategory, image_name, images_dir)
|
self.stdout.write(f" Subcategory: {subcat_name}")
|
||||||
self.stdout.write(f" Subcategory: {name}")
|
|
||||||
else:
|
|
||||||
# Items are Products
|
|
||||||
if not current_subcategory:
|
|
||||||
# Fallback if no header found yet
|
|
||||||
fb_name = "General"
|
|
||||||
current_subcategory, _ = SubcategoryModel.objects.get_or_create(
|
|
||||||
category=category,
|
|
||||||
name=fb_name
|
|
||||||
)
|
|
||||||
|
|
||||||
product, created = ProductsModel.objects.get_or_create(
|
# Products
|
||||||
name=name,
|
for i, prod_data in enumerate(subcat_data.get('products', [])):
|
||||||
subcategory=current_subcategory,
|
prod_name = prod_data.get('name', 'Unnamed Product')
|
||||||
defaults={'price': price if price > 0 else 0}
|
price = prod_data.get('price', 0)
|
||||||
)
|
image_name = prod_data.get('image')
|
||||||
if created:
|
|
||||||
|
product, _ = ProductsModel.objects.get_or_create(
|
||||||
|
subcategory=subcategory,
|
||||||
|
name=prod_name,
|
||||||
|
defaults={'price': price if price > 0 else 0}
|
||||||
|
)
|
||||||
if image_name:
|
if image_name:
|
||||||
self.attach_image(product, image_name, images_dir)
|
self.attach_image(product, image_name, images_dir)
|
||||||
self.stdout.write(f" Added Product: {name}")
|
# Attach first product's image to the subcategory if it hasn't one
|
||||||
|
if i == 0 and not subcategory.image:
|
||||||
product_map[(filial_name, json_id)] = product
|
self.attach_image(subcategory, image_name, images_dir)
|
||||||
|
|
||||||
# 2. Process Food Detail Containers (Subproducts)
|
# Subproducts (Variants)
|
||||||
food_detail_files = sorted(json_dir.glob('FoodDetailContainer*.json'))
|
for var_data in prod_data.get('variants', []):
|
||||||
for file_path in food_detail_files:
|
var_name = var_data.get('name', 'Unnamed Variant')
|
||||||
file_name = file_path.name
|
var_price = var_data.get('price', 0)
|
||||||
# Handle detail containers: FoodDetailContainerKaromat15.json -> Karomat
|
|
||||||
match = re.search(r'FoodDetailContainer(.*?)(?:\d+)?\.json', file_name)
|
SubProductModel.objects.get_or_create(
|
||||||
if not match:
|
product=product,
|
||||||
continue
|
name=var_name,
|
||||||
|
defaults={'price': var_price if var_price > 0 else 0}
|
||||||
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}")
|
|
||||||
|
|
||||||
def attach_image(self, instance, image_name, images_dir):
|
def attach_image(self, instance, image_name, images_dir):
|
||||||
if not image_name:
|
if not image_name:
|
||||||
|
|||||||
8036
menu_full.json
Normal file
8036
menu_full.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user