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

如何实现django-filter中过滤器的联动依赖功能

Django-Filter 实现过滤器依赖联动

以下示例以「选择交易对手(CounterParty)后,仅显示该交易对手关联的对象(ObjectList)」为例,你可以根据自己的业务字段(比如name和car)调整对应逻辑。

后端动态调整过滤器QuerySet

核心思路是在FilterSet初始化时,根据已提交的过滤参数,动态修改关联过滤器的可选范围。修改你的filters.py如下:

import django_filters
from django.db.models import Q
from common.filters import CustomDateRangeWidget
from common.models import CounterParty, ObjectList
from .models import OpenPointList


class OpenPointFilter(django_filters.FilterSet):
    """
    用于按日期、交易对手名称和对象名称过滤OpenPointList模型的Django-filter类
    """

    CHOICES = (
        ('Closed', '已关闭'),
        ('Open', '已开启')
    )

    status = django_filters.ChoiceFilter(choices=CHOICES)
    # 添加交易对手过滤器
    counter_party = django_filters.ModelChoiceFilter(
        label='交易对手',
        queryset=CounterParty.objects.all()
    )
    # 初始化时先不指定对象过滤器的queryset,后续动态赋值
    open_point_object = django_filters.ModelChoiceFilter(
        label='关联对象',
        queryset=ObjectList.objects.none()
    )

    category_choice = django_filters.ModelChoiceFilter(
        label='分类',
        queryset=OpenPointList.objects.values_list('category', flat=True).distinct()
    )
    category = django_filters.CharFilter(method='custom_category_filter')

    class Meta:
        model = OpenPointList
        fields = (
            'counter_party',
            'open_point_object',
            'status',
            'category',
        )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 获取请求中已选择的交易对手ID
        counter_party_id = self.data.get('counter_party')
        if counter_party_id:
            # 更新对象过滤器的可选范围,仅显示该交易对手关联的对象
            self.filters['open_point_object'].queryset = ObjectList.objects.filter(
                counter_party_id=counter_party_id
            )
        else:
            # 未选择交易对手时,显示所有对象
            self.filters['open_point_object'].queryset = ObjectList.objects.all()

前端AJAX联动更新下拉选项

后端调整后,需要前端监听第一个过滤器的变化,实时请求更新第二个过滤器的选项。在你的模板中添加以下代码:

<!-- 表单渲染完成后添加 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
    // 获取交易对手下拉框(ID根据实际表单渲染结果调整)
    const counterPartySelect = document.getElementById('id_counter_party');
    // 获取关联对象下拉框
    const objectSelect = document.getElementById('id_open_point_object');

    counterPartySelect.addEventListener('change', function() {
        const counterPartyId = this.value;
        // 发送AJAX请求获取对应对象列表
        fetch(`/get_objects/?counter_party_id=${counterPartyId}`)
            .then(response => response.json())
            .then(data => {
                // 清空现有选项
                objectSelect.innerHTML = '<option value="">---------</option>';
                // 追加新选项(假设ObjectList模型有name字段用于显示)
                data.forEach(obj => {
                    const option = document.createElement('option');
                    option.value = obj.id;
                    option.textContent = obj.name;
                    objectSelect.appendChild(option);
                });
            });
    });
});
</script>

配套视图与路由

在views.py中添加返回JSON数据的视图:

from django.http import JsonResponse
from common.models import ObjectList

def get_objects(request):
    counter_party_id = request.GET.get('counter_party_id')
    objects = []
    if counter_party_id:
        # 仅返回需要的字段(ID和显示名称)
        objects = ObjectList.objects.filter(counter_party_id=counter_party_id).values('id', 'name')
    return JsonResponse(list(objects), safe=False)

在urls.py中添加对应路由:

from django.urls import path
from .views import get_objects

urlpatterns = [
    # 其他现有路由...
    path('get_objects/', get_objects, name='get_objects'),
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:33:09