54 lines
2.5 KiB
Python
54 lines
2.5 KiB
Python
from django.core.management.base import BaseCommand
|
||
|
||
from meals.models import Dish
|
||
|
||
TYPE_MAP = {'荤菜': 'meat', '素菜': 'veg', '汤': 'soup', '主食': 'staple'}
|
||
TYPE_MAP_REV = {v: k for k, v in TYPE_MAP.items()}
|
||
|
||
|
||
class Command(BaseCommand):
|
||
help = '从文本文件批量导入菜品。每行格式:类型|菜名|配料明细|蛋白质|脂肪|热量|菜系 (类型:荤菜/素菜/汤/主食,营养与菜系可省略)'
|
||
|
||
def add_arguments(self, parser):
|
||
parser.add_argument('file', help='菜品文本文件路径')
|
||
|
||
def handle(self, *args, **options):
|
||
path = options['file']
|
||
created, skipped = 0, 0
|
||
with open(path, encoding='utf-8-sig') as f:
|
||
for line_no, line in enumerate(f, 1):
|
||
line = line.strip()
|
||
if not line or line.startswith('#'):
|
||
continue
|
||
parts = [p.strip() for p in line.split('|')]
|
||
if len(parts) < 2:
|
||
self.stderr.write(f'第 {line_no} 行格式错误,已跳过: {line}')
|
||
skipped += 1
|
||
continue
|
||
label, name = parts[0], parts[1]
|
||
dish_type = TYPE_MAP.get(label)
|
||
if not dish_type or not name:
|
||
self.stderr.write(f'第 {line_no} 行类型或菜名无效,已跳过: {line}')
|
||
skipped += 1
|
||
continue
|
||
ingredient = parts[2] if len(parts) > 2 else ''
|
||
protein = float(parts[3]) if len(parts) > 3 and parts[3] else 0
|
||
fat = float(parts[4]) if len(parts) > 4 and parts[4] else 0
|
||
calorie = int(float(parts[5])) if len(parts) > 5 and parts[5] else 0
|
||
cuisine = parts[6] if len(parts) > 6 and parts[6] else '家常菜'
|
||
dish, is_created = Dish.objects.update_or_create(
|
||
name=name,
|
||
defaults={
|
||
'dish_type': dish_type,
|
||
'cuisine': cuisine,
|
||
'ingredient_detail': ingredient,
|
||
'protein': protein,
|
||
'fat': fat,
|
||
'calorie': calorie,
|
||
},
|
||
)
|
||
if is_created:
|
||
created += 1
|
||
self.stdout.write(f'新增: {label} - {name}({cuisine})')
|
||
self.stdout.write(self.style.SUCCESS(f'导入完成:新增 {created} 道,跳过 {skipped} 条'))
|