import yangilandi
This commit is contained in:
@@ -9,6 +9,8 @@ class CategoryFilter(filters.FilterSet):
|
||||
fields = [
|
||||
"name",
|
||||
"filial",
|
||||
"filial__name",
|
||||
"type",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ class Command(BaseCommand):
|
||||
json_dir = base_dir / 'assets' / 'json'
|
||||
images_dir = base_dir / 'assets' / 'images'
|
||||
|
||||
# 0. Clear Database
|
||||
self.stdout.write(self.style.WARNING("Clearing existing data..."))
|
||||
FilialModel.objects.all().delete()
|
||||
# Cascading deletes should clear Categories, Subcategories, Products, and SubProducts
|
||||
|
||||
product_map = {} # Maps (filial_name, item_id) to ProductsModel instance
|
||||
|
||||
# 1. Process Main Food Containers
|
||||
@@ -51,21 +56,34 @@ class Command(BaseCommand):
|
||||
price = item.get('price', 0)
|
||||
image_name = item.get('image')
|
||||
json_id = item.get('id')
|
||||
item_type = item.get('type', '')
|
||||
|
||||
if is_header:
|
||||
# Create Category and Subcategory
|
||||
# Determine if this category is Bar or Restaurant
|
||||
# Usually anything with "BAR" in type string is Bar
|
||||
cat_type = CategoryModel.CategoryType.RESTAURANT
|
||||
if "BAR" in item_type.upper():
|
||||
cat_type = CategoryModel.CategoryType.BAR
|
||||
|
||||
# Create Category
|
||||
current_category, created = CategoryModel.objects.get_or_create(
|
||||
filial=filial,
|
||||
name=name
|
||||
name=name,
|
||||
defaults={'type': cat_type}
|
||||
)
|
||||
if created and image_name:
|
||||
self.attach_image(current_category, image_name, images_dir)
|
||||
elif not created and current_category.type != cat_type:
|
||||
# Update type if it was created differently before
|
||||
current_category.type = cat_type
|
||||
current_category.save()
|
||||
|
||||
# Link Subcategory (using the same name for now as the JSON doesn't define a sub-level)
|
||||
current_subcategory, created = SubcategoryModel.objects.get_or_create(
|
||||
category=current_category,
|
||||
name=name
|
||||
)
|
||||
self.stdout.write(f" Category/Subcategory: {name}")
|
||||
self.stdout.write(f" Category({cat_type}): {name}")
|
||||
else:
|
||||
if not current_subcategory:
|
||||
# Fallback if no header found yet
|
||||
@@ -80,7 +98,7 @@ class Command(BaseCommand):
|
||||
)
|
||||
|
||||
# Create Product
|
||||
# We use get_or_create with name and subcategory to avoid obvious duplicates
|
||||
# We use get_or_create to avoid duplicates within the same subcategory
|
||||
product, created = ProductsModel.objects.get_or_create(
|
||||
name=name,
|
||||
subcategory=current_subcategory,
|
||||
@@ -91,7 +109,6 @@ class Command(BaseCommand):
|
||||
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)
|
||||
@@ -124,12 +141,8 @@ class Command(BaseCommand):
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
18
core/apps/api/migrations/0003_categorymodel_type.py
Normal file
18
core/apps/api/migrations/0003_categorymodel_type.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.7 on 2026-03-27 14:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0002_filialmodel_categorymodel_filial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='categorymodel',
|
||||
name='type',
|
||||
field=models.CharField(choices=[('RESTAURANT', 'Restaurant'), ('BAR', 'Bar')], default='RESTAURANT', max_length=20, verbose_name='type'),
|
||||
),
|
||||
]
|
||||
@@ -21,6 +21,10 @@ class FilialModel(AbstractBaseModel):
|
||||
|
||||
|
||||
class CategoryModel(AbstractBaseModel):
|
||||
class CategoryType(models.TextChoices):
|
||||
RESTAURANT = "RESTAURANT", _("Restaurant")
|
||||
BAR = "BAR", _("Bar")
|
||||
|
||||
filial = models.ForeignKey(
|
||||
FilialModel,
|
||||
verbose_name=_("filial"),
|
||||
@@ -30,10 +34,16 @@ class CategoryModel(AbstractBaseModel):
|
||||
blank=True,
|
||||
)
|
||||
name = models.CharField(verbose_name=_("name"), max_length=255)
|
||||
type = models.CharField(
|
||||
verbose_name=_("type"),
|
||||
max_length=20,
|
||||
choices=CategoryType.choices,
|
||||
default=CategoryType.RESTAURANT,
|
||||
)
|
||||
image = models.ImageField(verbose_name=_("image"), upload_to="categories/", null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return f"{self.name} ({self.type})"
|
||||
|
||||
@classmethod
|
||||
def _baker(cls):
|
||||
|
||||
@@ -12,6 +12,7 @@ class BaseCategorySerializer(serializers.ModelSerializer):
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"image",
|
||||
"subcategories",
|
||||
]
|
||||
@@ -22,6 +23,7 @@ class ListCategorySerializer(BaseCategorySerializer):
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"image",
|
||||
"subcategories",
|
||||
]
|
||||
|
||||
0
resources/logs/.gitignore
vendored
Normal file → Executable file
0
resources/logs/.gitignore
vendored
Normal file → Executable file
Reference in New Issue
Block a user