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

如何用DRF、django-filter基于HyperlinkedIdentityField做多值查询过滤

问题修复方案

核心问题原因

  1. 之前自定义过滤器循环执行过滤的逻辑等价于生成driver=1 AND driver=2的查询条件,不存在同时属于两个司机的合同,所以只会保留最后一次过滤的结果
  2. 默认的FilterSet对关联字段生成的是ModelChoiceFilter,仅支持传入ID值,传入超链接字符串会触发参数校验失败,返回400错误

修复后代码

1. 自定义过滤器实现

from django_filters import BaseCSVFilter, CharFilter
from django.urls import resolve
from urllib.parse import urlparse, unquote

def get_id_from_url(url):
    # 可根据需要添加异常捕获,处理无效URL的场景
    return int(resolve(urlparse(unquote(url)).path).kwargs.get('pk'))

class CustomHyperlinkedIdentityFilterList(BaseCSVFilter, CharFilter):
    def filter(self, qs, value):
        if not value:
            return qs
        # 批量转换所有超链接为资源ID
        target_ids = [get_id_from_url(item) for item in value]
        # 用IN查询一次性匹配所有关联对象
        return qs.filter(**{f"{self.field_name}__id__in": target_ids})

2. 过滤器配置

class ContractFilter(FilterSet):
    driver = CustomHyperlinkedIdentityFilterList(field_name='driver')
    
    class Meta:
        model = Contract
        fields = ['driver']

效果验证

发起示例请求:/api/contract/?driver=http://localhost:8000/api/driver/1,http://localhost:8000/api/driver/2
即可返回两个司机对应的所有合同数据,符合业务需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:45:01