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

如何在Django-graphene中实现基于外键的查询过滤?

核心问题原因

  1. 解析器命名不符合graphene规则:graphene要求查询字段对应的解析器必须按照resolve_<字段名>的格式命名,你定义的查询字段是todoList,但是你写的解析器名字是resolve_all_todo,完全无法匹配触发,所以graphene直接返回了TodoList模型的全部数据,导致你的硬编码过滤逻辑不生效。
  2. 未给查询字段定义可传入的过滤参数,所以无法动态根据外键值过滤返回结果。

修复方案(基础版,支持外键传参过滤)

直接修改schema.py代码如下:

import graphene
from graphene_django import DjangoObjectType, DjangoListField
from .models import TodoList
from django.contrib.auth.models import User

class TodoView(DjangoObjectType):
    class Meta:
        model = TodoList
        fields = ('id', 'title', 'date', 'text', 'userId')

class UserType(DjangoObjectType):
    class Meta:
        model = User

class TodoQuery(graphene.ObjectType):
    # 给todoList字段添加user_id过滤参数
    todoList = DjangoListField(TodoView, user_id=graphene.Int(required=False))

    # 修正解析器命名,匹配字段名
    def resolve_todoList(root, info, user_id=None, **kwargs):
        queryset = TodoList.objects.all()
        # 传入user_id时按外键过滤
        if user_id:
            queryset = queryset.filter(userId=user_id)
        return queryset

请求示例

查询userId为2的所有待办:

{
  todoList(userId: 2) {
    id
    title
    date
    text
  }
}

进阶方案(支持多规则过滤,无需手动写解析器)

如果需要更复杂的过滤(比如模糊查询、时间范围过滤、外键关联字段过滤),可以使用django-filter实现自动过滤:

  1. 先安装依赖:pip install django-filter
  2. 修改settings.py,将django_filters加入INSTALLED_APPS
  3. 修改schema.py代码:
import graphene
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from .models import TodoList
from django.contrib.auth.models import User

class TodoView(DjangoObjectType):
    class Meta:
        model = TodoList
        fields = ('id', 'title', 'date', 'text', 'userId')
        # 配置支持的过滤规则
        filter_fields = {
            'userId': ['exact'],
            'title': ['exact', 'icontains'],
            'date': ['exact', 'gt', 'lt']
        }
        interfaces = (graphene.relay.Node,)

class UserType(DjangoObjectType):
    class Meta:
        model = User

class TodoQuery(graphene.ObjectType):
    todoList = DjangoFilterConnectionField(TodoView)

请求示例

查询userId为2、标题包含"test"的待办:

{
  todoList(userId: 2, title_Icontains: "test") {
    edges {
      node {
        id
        title
        date
        text
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者M N Tushar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:45:03