You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用django-filter基于反向外键字段实现筛选功能?

解决Django ListAPIView中跨关联模型字段筛选的问题

嘿,我明白你现在的需求——想通过关联模型TDebtData里的agr_num字段来筛选TDebtor实例对吧?默认的filterset_fields只能处理当前模型的字段,所以咱们得自定义一个FilterSet来实现跨表筛选。下面是具体的步骤:

1. 准备工作(确保依赖已安装)

首先确认你已经安装了django-filter,如果还没装,先执行:

pip install django-filter

然后在你的views文件里导入必要的模块:

from django_filters import FilterSet, CharFilter
from .models import TDebtor, TDebtData
from rest_framework import generics

2. 自定义FilterSet类

创建一个继承自FilterSet的类,专门处理TDebtor的筛选逻辑,添加针对agr_num的跨表筛选规则:

class TDebtorFilter(FilterSet):
    # 定义agr_num筛选字段,通过双下划线关联到关联模型的字段
    # lookup_expr可选'exact'(精确匹配)或'icontains'(模糊匹配),按需调整
    agr_num = CharFilter(field_name='debtor_debt_data__agr_num', lookup_expr='exact')

    class Meta:
        model = TDebtor
        # 保留原有的TDebtor自身字段筛选,同时加入新的agr_num
        fields = ['iin', 'first_name', 'surname', 'middle_name', 'birth_date', 'alive', 'agr_num']

3. 修改你的ListAPIView

把原来的filterset_fields替换成自定义的filterset_class,另外注意你原来代码里的for i in queryset:放在类定义里是错误的(类初始化阶段queryset还未执行,会导致不必要的循环),建议移除这段调试代码。修改后的View如下:

class ProductList(generics.ListAPIView):
    # 优化预取逻辑:不需要在Prefetch里再加select_related('id_debtor'),因为已经从TDebtor侧预取关联数据
    queryset = TDebtor.objects.prefetch_related('debtor_debt_data')
    serializer_class = TDebtorSerializer
    filter_backends = [DjangoFilterBackend]
    # 使用自定义的FilterSet替代默认字段配置
    filterset_class = TDebtorFilter

原理说明

  • Django的双下划线__语法支持跨模型关联字段的查询,debtor_debt_data__agr_num表示通过TDebtor的反向关联debtor_debt_data,找到对应TDebtData实例的agr_num字段。
  • 自定义FilterSet可以突破默认filterset_fields的限制,让我们轻松实现关联模型字段的筛选逻辑。

现在你就可以通过传入agr_num=1238HFD32这样的参数,筛选出拥有对应债务编号的债务人实例了!

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

火山引擎 最新活动