如何在Django-graphene中实现基于外键的查询过滤?
核心问题原因
- 解析器命名不符合graphene规则:graphene要求查询字段对应的解析器必须按照
resolve_<字段名>的格式命名,你定义的查询字段是todoList,但是你写的解析器名字是resolve_all_todo,完全无法匹配触发,所以graphene直接返回了TodoList模型的全部数据,导致你的硬编码过滤逻辑不生效。 - 未给查询字段定义可传入的过滤参数,所以无法动态根据外键值过滤返回结果。
修复方案(基础版,支持外键传参过滤)
直接修改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实现自动过滤:
- 先安装依赖:
pip install django-filter - 修改
settings.py,将django_filters加入INSTALLED_APPS - 修改
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
相关产品推荐
相关产品推荐

