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

Django Graphene嵌套过滤无匹配子数据时不返回父记录方法

问题原因

你当前的实现存在两个核心问题:

  • GraphQL执行顺序是自顶向下的,先解析父级purchases字段拿到所有采购订单,再逐个解析每个订单下的products子字段。你把产品名过滤参数写在子级products上,父级查询时完全感知不到这个过滤条件,自然会把当前用户的所有采购订单全查出来。
  • 你自定义的resolve_products方法原本没有使用传入的过滤参数,即使后续过滤器做了一层子项过滤,本质还是在已查出的父订单范围内筛选子产品,不会回过去剔除没有匹配产品的父订单。
修复步骤

1. 给采购订单类型新增跨表产品过滤能力

修改Purchases类的Meta.filter_fields配置,增加关联产品表的过滤规则,支持在查询采购订单时直接按下属产品名筛选:

class Purchases(DjangoObjectType):
    id = graphene.ID(source='pk', required=True)
    products = ArtsyConnectionField(PurchasesProducts)

    class Meta:
        model = purchase_orders
        interfaces = (relay.Node,)
        filter_fields = {
            'date': ['gt', 'lt', 'isnull'],
            'username': ['icontains'],
            # 新增跨关联表的产品名过滤
            'products__product_name': ['icontains']
        }
        connection_class = ArtsyConnection

2. 调整采购订单查询逻辑,提前过滤无匹配产品的订单

修改resolve_purchases方法,识别产品名过滤参数,在查询采购订单阶段就通过外键关联筛掉不存在匹配产品的订单,注意加distinct()避免一个订单下多个匹配产品时返回重复数据:

@staticmethod
def resolve_purchases(self, info, **kwargs):
    queryset = purchase_orders.objects.filter(user_id=info.context.user.id)
    # 提取产品名过滤参数
    product_name_keyword = kwargs.get('products_ProductName_Icontains')
    if product_name_keyword:
        queryset = queryset.filter(
            products__product_name__icontains=product_name_keyword
        ).distinct()
    # 保留原有排序、日期过滤逻辑
    return queryset.order_by("-date")

3. 补全子产品解析的过滤逻辑

修改resolve_products方法,把传入的过滤参数应用到产品查询上,保证每个订单下返回的产品也只有匹配项:

@staticmethod
def resolve_products(self, info, **kwargs):
    queryset = purchase_orders_products.objects.filter(order_id=self.id)
    product_name_keyword = kwargs.get('productName_Icontains')
    if product_name_keyword:
        queryset = queryset.filter(product_name__icontains=product_name_keyword)
    return queryset.order_by('product_name').all()

4. 调整GraphQL查询参数位置

将产品名过滤参数上移到父级purchases查询上(子级可以保留相同参数做双重校验),修改后的查询如下:

{
  dateFilterList
  purchases(first: 15, after: "", products_ProductName_Icontains: "access") {
    pageCursors {
      ...
    }
    edges {
      node {
        id
        username
        ...
        products(productName_Icontains: "access") {
          edges {
            node {
              id
              productId
              productName
              productNumber
            }
          }
        }
      }
    }
  }
}
最终效果

修改后查询时,没有任何匹配产品的采购订单(比如你示例中username为ThisIsUsername、products.edges为空的订单)会在数据库查询阶段就被过滤掉,返回结果里只会保留包含匹配产品的采购订单,每个订单下的产品列表也仅展示符合搜索条件的产品项,不会再出现空产品列表的无效订单。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:51:20