重写Django Admin的get_queryset()方法遇代理模型显示问题求助
问题原因
当ProxyCategoryAdmin继承CategoryAdmin后,调用super().get_queryset(request)时会先执行CategoryAdmin的get_queryset方法,已经将查询集过滤为language='en'的数据,之后再叠加filter(language='zh'),两个条件的交集为空,自然无法显示任何对象。
解决方法
在ProxyCategoryAdmin的get_queryset方法中,跳过父类CategoryAdmin的过滤逻辑,直接调用最顶层的admin.ModelAdmin的get_queryset方法获取原始未过滤的查询集,再进行自身的语言过滤。
修改后的admin.py代码如下:
from django.contrib import admin from .models import Category, ProxyCategory @admin.register(Category) class CategoryAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) return qs.filter(language='en') @admin.register(ProxyCategory) class ProxyCategoryAdmin(CategoryAdmin): def get_queryset(self, request): # 直接调用ModelAdmin的get_queryset,绕过CategoryAdmin的过滤 qs = admin.ModelAdmin.get_queryset(self, request) return qs.filter(language='zh')
补充优化方案
如果后续还有更多代理模型需要类似的语言过滤,也可以重构父类逻辑,抽离通用的基础Admin类,让CategoryAdmin和各个代理模型的Admin都直接继承这个基础类,避免父类的过滤逻辑传递给子类。例如:
class BaseCategoryAdmin(admin.ModelAdmin): # 这里放通用配置,比如list_display、list_filter等 pass @admin.register(Category) class CategoryAdmin(BaseCategoryAdmin): def get_queryset(self, request): qs = super().get_queryset(request) return qs.filter(language='en') @admin.register(ProxyCategory) class ProxyCategoryAdmin(BaseCategoryAdmin): def get_queryset(self, request): qs = super().get_queryset(request) return qs.filter(language='zh')
这种方式结构更清晰,也不会出现子类继承父类过滤逻辑的冲突问题。
内容的提问来源于stack exchange,提问作者mirodil
相关产品推荐
相关产品推荐

