如何在Django Admin过滤器中使用自定义模型管理器方法
在Django Admin中使用自定义模型管理器方法作为过滤器
嘿,这事儿其实不难,咱们一步步来实现:
首先,先确认你的MockTest模型已经关联了自定义管理器——应该已经在模型里加了这行吧?如果还没,先补上:
from django.db import models from django.utils import timezone # 建议用这个代替datetime.now(),避免时区问题 class MockTest(models.Model): start_date = models.DateTimeField() end_date = models.DateTimeField() # 其他字段... objects = MockTestManager() # 关联自定义管理器
接下来,我们需要自定义一个Admin过滤器类,继承django.contrib.admin.SimpleListFilter,把你的管理器方法整合进去:
from django.contrib.admin import SimpleListFilter class MockTestStatusFilter(SimpleListFilter): # 过滤器在Admin页面显示的标题 title = '测试状态' # URL中用来传递过滤参数的名称 parameter_name = 'test_status' def lookups(self, request, model_admin): # 定义过滤器的选项:(参数值, 显示文本) return ( ('upcoming', '即将开始的测试'), ('past', '已结束的测试'), ) def queryset(self, request, queryset): # 根据选中的选项,调用对应的管理器方法返回过滤后的查询集 if self.value() == 'upcoming': return queryset.model.objects.upcoming_tests() if self.value() == 'past': return queryset.model.objects.past_tests() # 如果没选任何选项,返回原始查询集 return queryset
然后,把这个过滤器注册到你的MockTestAdmin类里:
from django.contrib import admin @admin.register(MockTest) class MockTestAdmin(admin.ModelAdmin): list_display = ('start_date', 'end_date',) # 你需要显示的字段 list_filter = (MockTestStatusFilter,) # 加上自定义过滤器
额外提醒:
- 记得把你原来管理器里的
datetime.now()替换成timezone.now(),不然如果你的项目开启了时区支持(Django2.0默认推荐开启),会出现时间不匹配的问题。修改后的管理器方法如下:
class MockTestQuerySet(models.query.QuerySet): def upcoming(self): return self.filter(start_date__gte=timezone.now()) def past(self): return self.filter(end_date__lte=timezone.now())
- 如果你想让过滤器默认选中某个选项,可以在
queryset方法里加个默认逻辑,比如如果没有参数时默认显示即将开始的测试,不过一般保持默认返回全部就好。
这样配置完之后,你在Admin的MockTest列表页面就能看到这个自定义过滤器,选择对应的选项就能调用你写的管理器方法过滤数据啦!
内容的提问来源于stack exchange,提问作者Anuj TBE
相关产品推荐
相关产品推荐

