You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:54:51