- 菜品营养按食物成分表+烹饪方式校准(calibrate_nutrition 命令) - 后台接入 jazzmin 主题美化,移除 Google Fonts(模板覆盖) - 前端/后台静态资源指向 qnycdn 对象存储 CDN(vite base + DJANGO_STATIC_URL) - 菜单标题学校名称/周数可编辑,日期随周数计算 - admin 搜索支持拼音首字母/全拼(Dish.pinyin 索引,pypinyin) - Dockerfile 使用清华 pip 镜像源
57 lines
2.5 KiB
Python
57 lines
2.5 KiB
Python
from django.contrib import admin
|
|
from django.utils.html import format_html, mark_safe
|
|
|
|
from .models import Dish
|
|
|
|
|
|
@admin.action(description='启用所选菜品(参与自动生成)')
|
|
def activate_dishes(modeladmin, request, queryset):
|
|
queryset.update(is_active=True)
|
|
|
|
|
|
@admin.action(description='停用所选菜品(不再参与自动生成)')
|
|
def deactivate_dishes(modeladmin, request, queryset):
|
|
queryset.update(is_active=False)
|
|
|
|
|
|
@admin.register(Dish)
|
|
class DishAdmin(admin.ModelAdmin):
|
|
list_display = ('name', 'cuisine', 'dish_type_display', 'ingredient_detail', 'protein', 'fat', 'calorie', 'nutri_badge', 'is_active', 'created_at')
|
|
list_filter = ('dish_type', 'cuisine', 'is_active')
|
|
search_fields = ('name', 'ingredient_detail', 'cuisine', 'pinyin')
|
|
list_editable = ('cuisine', 'ingredient_detail', 'protein', 'fat', 'calorie', 'is_active')
|
|
list_per_page = 50
|
|
actions = [activate_dishes, deactivate_dishes]
|
|
fieldsets = (
|
|
(None, {'fields': ('name', 'dish_type', 'cuisine', 'is_active')}),
|
|
('营养信息', {'fields': ('ingredient_detail', 'protein', 'fat', 'calorie')}),
|
|
('其他', {'fields': ('description',), 'classes': ('collapse',)}),
|
|
)
|
|
|
|
@admin.display(description='营养提示', ordering='calorie')
|
|
def nutri_badge(self, obj):
|
|
badges = []
|
|
if obj.dish_type == 'meat' and obj.fat >= 20:
|
|
badges.append('<span class="badge badge-danger">高脂</span>')
|
|
if obj.dish_type == 'meat' and obj.calorie >= 300:
|
|
badges.append('<span class="badge badge-warning">高热量</span>')
|
|
if obj.dish_type in ('meat', 'veg') and obj.protein >= 15:
|
|
badges.append('<span class="badge badge-success">高蛋白</span>')
|
|
if obj.dish_type == 'veg' and obj.fat <= 3 and obj.calorie <= 60:
|
|
badges.append('<span class="badge badge-info">清淡</span>')
|
|
return mark_safe(' '.join(badges)) if badges else '—'
|
|
|
|
@admin.display(description='类型')
|
|
def dish_type_display(self, obj):
|
|
colors = {'meat': '#d9534f', 'veg': '#5cb85c', 'soup': '#5bc0de', 'staple': '#f0ad4e'}
|
|
return format_html(
|
|
'<span style="color:{};font-weight:600">{}</span>',
|
|
colors.get(obj.dish_type, '#999'),
|
|
dict(Dish.TYPE_CHOICES).get(obj.dish_type, obj.dish_type),
|
|
)
|
|
|
|
|
|
admin.site.site_header = '学校订餐菜单管理系统'
|
|
admin.site.site_title = '学校订餐菜单管理'
|
|
admin.site.index_title = '菜单管理后台'
|