from django.contrib import admin, messages from django.core.cache import cache from import_export.admin import ImportExportModelAdmin from base.models import MainMenu, BaseInfo, LinkCategory, FriendLink, PictureLink # —————— 主菜单 —————— @admin.register(MainMenu) class MainMenuAdmin(ImportExportModelAdmin): list_display = ('display_name', 'code', 'url', 'parent', 'order', 'visible') list_editable = ('order', 'visible') list_filter = ('parent', 'visible') search_fields = ('title', 'url') ordering = ('id',) def display_name(self, obj): """在列表中显示层级缩进""" if obj.is_sub: return f"  └─ {obj.title}" # 使用全角空格+符号模拟缩进 return obj.title display_name.short_description = '板块名称' display_name.admin_order_field = 'name' def is_enabled(self, obj): return obj.visible is_enabled.boolean = True is_enabled.short_description = '启用' def formfield_for_foreignkey(self, db_field, request, **kwargs): """限制 parent 只能选择主板块(无父级的板块)""" if db_field.name == "parent": kwargs["queryset"] = MainMenu.objects.filter(parent__isnull=True, is_external=False) return super().formfield_for_foreignkey(db_field, request, **kwargs) def get_queryset(self, request): """优化查询,避免 N+1""" return super().get_queryset(request).select_related('parent') # 1. 注册分类管理 @admin.register(LinkCategory) class LinkCategoryAdmin(ImportExportModelAdmin): list_display = ('name', 'code', 'order', 'is_active') list_editable = ('order', 'is_active') # 2. 注册链接管理 @admin.register(FriendLink) class FriendLinkAdmin(ImportExportModelAdmin): list_display = ('name', 'category', 'url', 'order', 'is_active') list_filter = ('category', 'is_active') # 左侧过滤器,方便筛选 search_fields = ('name', 'url') # 优化:在添加链接时,只显示启用的分类 def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "category": kwargs["queryset"] = LinkCategory.objects.filter(is_active=True) return super().formfield_for_foreignkey(db_field, request, **kwargs) @admin.register(PictureLink) class PictureLinkAdmin(admin.ModelAdmin): list_display = ['name', 'order', 'is_active', 'created_at'] def save_model(self, request, obj, form, change): # 1. 先执行 Model 的 save 方法(这里会触发逻辑判断和消息暂存) super().save_model(request, obj, form, change) # 2. 【关键】检查有没有暂存的消息 # 获取 key(如果是新建对象,obj.pk 此时已经有了,如果是内存中的临时对象则用 id) msg_key = obj.pk if obj.pk else id(obj) key = f"picture_count_limit_{msg_key}" msg = cache.get(key) # 缓存 30 秒 if msg: # 取出消息并弹窗 cache.delete(key) self.message_user(request, msg, level=messages.WARNING) # —————— 页脚链接 —————— @admin.register(BaseInfo) class BaseInfoAdmin(ImportExportModelAdmin): list_display = ('title', 'address', 'unit', 'postal', 'telephone', 'fax', 'filing') list_editable = ('postal', 'telephone', 'fax', 'unit', 'filing',)