Django Admin自定义ListFilter:关联模型日期过滤实现技术问询
搞定Django Admin关联模型日期过滤器
没问题,我来帮你实现这个需求——在Avaria的Admin页面里,通过关联的Pavimentacao模型的date字段来过滤数据。我们需要写一个自定义的列表过滤器,具体步骤如下:
1. 编写自定义过滤器类
在你的admin.py文件中,添加这个继承自SimpleListFilter的过滤器类:
from django.contrib import admin from django.utils.translation import gettext_lazy as _ from .models import Avaria, Pavimentacao from datetime import timedelta, date class PavimentacaoDateFilter(admin.SimpleListFilter): # 过滤器在Admin页面显示的标题(适配你的葡语模型名,可按需修改) title = _('Data da Pavimentação') # URL中用来标识这个过滤器的参数名,自定义即可 parameter_name = 'pavimentacao_date' def lookups(self, request, model_admin): # 这里提供两种过滤器选项方案,选一种适合你的即可: # 方案一:显示所有已存在的Pavimentacao日期(去重+倒序排列) existing_dates = Pavimentacao.objects.values_list('date', flat=True).distinct().order_by('-date') return [(date.strftime('%Y-%m-%d'), date.strftime('%d/%m/%Y')) for date in existing_dates if date] # 方案二:显示时间范围选项(比如最近7天、本月等),注释掉方案一,打开下面这段即可 # return [ # ('last_7_days', _('Últimos 7 dias')), # ('this_month', _('Este mês')), # ('last_month', _('Último mês')), # ] def queryset(self, request, queryset): # 根据选中的选项过滤Avaria查询集 filter_value = self.value() if not filter_value: return queryset # 对应方案一:过滤关联日期等于选中值的Avaria return queryset.filter(AvariaObjects__date=filter_value) # 对应方案二:根据不同的时间范围过滤,注释掉上面的return,打开下面这段 # if filter_value == 'last_7_days': # seven_days_ago = date.today() - timedelta(days=7) # return queryset.filter(AvariaObjects__date__gte=seven_days_ago) # elif filter_value == 'this_month': # today = date.today() # return queryset.filter(AvariaObjects__date__year=today.year, AvariaObjects__date__month=today.month) # elif filter_value == 'last_month': # today = date.today() # last_month = today.month - 1 if today.month > 1 else 12 # last_year = today.year if today.month > 1 else today.year - 1 # return queryset.filter(AvariaObjects__date__year=last_year, AvariaObjects__date__month=last_month)
2. 将过滤器添加到AvariaAdmin
修改你的AvariaAdmin类,把自定义过滤器加入list_filter列表:
class AvariaAdmin(admin.ModelAdmin): # 把自定义过滤器加到列表过滤器中 list_filter = (PavimentacaoDateFilter,)
小提示:
- 注意关联模型的
related_name是AvariaObjects,所以过滤时要用双下划线连接字段:AvariaObjects__date - 如果你的Pavimentacao数据量很大,方案一的日期列表会过长,这种情况下方案二的时间范围选项会更实用
- 可以根据你的实际需求调整过滤器的标题和选项文本,适配你的语言环境
这样设置完成后,你在Avaria的Admin列表页就能看到这个日期过滤器,选择对应的选项就能过滤出符合条件的Avaria对象啦!
内容的提问来源于stack exchange,提问作者Pedro Mariz
相关产品推荐
相关产品推荐

