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

Django Admin过滤器添加双数值字段后无法获取值的问题求助

解决Django Admin数值范围过滤器的参数传递问题

我之前也碰到过一模一样的情况,默认的过滤器只支持单个参数,所以当你加了第二个输入框后,self.value()自然拿不到值了。下面是完整的解决方案,分成几个步骤来实现:

1. 自定义过滤器类

首先我们要写一个继承自SimpleListFilter的过滤器类,不在lookups里定义选项,而是自己写模板,然后从request.GET里直接获取两个字段的值:

from django.contrib import admin
from django.utils.translation import gettext_lazy as _

class NumberRangeFilter(admin.SimpleListFilter):
    title = _('数值范围')
    parameter_name = 'is_within_range'  # 仅作为过滤器标识,实际用不到它取值

    def lookups(self, request, model_admin):
        # 返回空,因为我们用自定义模板展示输入框
        return ()

    def queryset(self, request, queryset):
        # 从request.GET里获取两个输入框的值
        min_val = request.GET.get('is_within_min')
        max_val = request.GET.get('is_within_max')
        
        # 根据输入值组合过滤queryset,替换成你实际要过滤的字段(比如score)
        if min_val and max_val:
            return queryset.filter(score__gte=float(min_val), score__lte=float(max_val))
        elif min_val:
            return queryset.filter(score__gte=float(min_val))
        elif max_val:
            return queryset.filter(score__lte=float(max_val))
        # 没填值就返回原queryset
        return queryset

    # 指定自定义模板路径
    template = 'admin/number_range_filter.html'

2. 创建自定义过滤器模板

在你的Django项目的templates/admin目录下创建number_range_filter.html文件,内容如下(两个输入框的name要和过滤器类里取的键对应):

{% load i18n custom_filters %}
<h3>{% blocktrans with title=title %}By {{ title }}{% endblocktrans %}</h3>
<div class="form-row" style="display:flex; gap:8px; align-items:center;">
    <input type="number" step="0.1" max="0.9" min="0.1" name="is_within_min" placeholder="最小值" value="{{ request.GET.is_within_min }}">
    <span>至</span>
    <input type="number" step="0.1" max="0.9" min="0.1" name="is_within_max" placeholder="最大值" value="{{ request.GET.is_within_max }}">
    <button type="submit" class="button">{% trans '过滤' %}</button>
    {% if request.GET.is_within_min or request.GET.is_within_max %}
        <a href="{{ request.path }}?{{ request.GET|remove:'is_within_min is_within_max' }}" class="button">{% trans '重置' %}</a>
    {% endif %}
</div>

补充:实现重置按钮的过滤器

上面模板用到了remove模板过滤器来清除参数,需要自己实现:
在你的app的templatetags目录下创建custom_filters.py:

from django import template

register = template.Library()

@register.filter
def remove(query_dict, keys):
    keys = keys.split()
    qd = query_dict.copy()
    for key in keys:
        qd.pop(key, None)
    return qd.urlencode()

3. 在Admin中注册过滤器

最后在你的ModelAdmin里添加这个过滤器:

@admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):
    list_filter = (NumberRangeFilter,)
    # 其他Admin配置...

为什么self.value()没用?

因为self.value()是SimpleListFilter用来获取当前过滤器对应的单个参数的值的,而我们现在是两个独立的参数,所以它自然返回None。直接从request.GET里取是最直接的方式,还能灵活处理两个输入框的各种组合情况。

内容的提问来源于stack exchange,提问作者mhs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:20:15