石墨烯 Django 和 react-router-relay
Posted
技术标签:
【中文标题】石墨烯 Django 和 react-router-relay【英文标题】:Graphene Django and react-router-relay 【发布时间】:2017-08-20 20:45:01 【问题描述】:我在弄清楚 Graphene Django 应该如何与 react-router-relay 一起使用时遇到了很大的麻烦。假设我可以通过我的 Django 服务器上的 GraphiQL 控制台很好地使用以下 GraphQL 查询:
query
allThreads
edges
node
id
这大概是 Graphene 对常用的 viewer
包装器的替代品,因为 Relay 不支持根查询上的连接。所以我知道 allThreads 实际上是一个节点(类型为 ThreadNodeConnection),并且有一个可以查询的边连接。
问题是我不知道如何将它与 Relay 一起使用,特别是 react-router-relay。我有一个 React 视图,上面有这样的片段(在其他地方有一个子 Thread 组件):
fragments:
store: () => Relay.QL`
fragment on Query
allThreads (first:300)
edges
node
// child's fragment included here
,
`,
,
Webpack 会根据我的实时模式检查它并喜欢它。然后我在我的 index.js 中为路由器创建以下内容:
const ViewerQueries =
store: () => Relay.QL`query allThreads(first:300) `
;
ReactDOM.render(
<Router
forceFetch
environment=Relay.Store
render=applyRouterMiddleware(useRelay)
history=browserHistory
>
<Route path='/' component=ThreadList queries=ViewerQueries />
</Router>
, document.getElementById('container')
)
我已经有点不确定了,因为我认为我做错了 ViewerQueries,但很难知道,因为其他人都使用它来适应他们的 GraphQL 连接上的 viewer
包装器,但 Graphene 有一个不同的包装器每个连接,所以这可能只适用于我的单一路线,但现在没关系。 Webpack 再次喜欢它反对模式。但是当我加载页面时,我收到一个“错误请求”和以下错误:
"F1 片段不能作为类型的对象在这里传播 ThreadNodeConnection 永远不能是 Query 类型”
老实说,这就是我无法继续的地方,因为我显然不了解 Graphene Django 如何构建架构,或者应该如何编写 GraphQL 片段,或者应该如何编写 Route 查询.问题是我无法弄清楚这些事情中的哪一个是错误的,而且似乎没有任何资源围绕着使用这些特定技术组合的人们。
为了完整起见,我的 Graphene Django 架构设置是(略微简化):
项目/线程/schema.py:
class ThreadNode(DjangoObjectType):
class Meta:
model = Thread
interfaces = (relay.Node, )
...
class Query(graphene.AbstractType):
all_threads = DjangoFilterConnectionField(ThreadNode)
thread = relay.Node.Field(ThreadNode, id=graphene.Int())
def resolve_all_threads(self, args, context, info):
return Thread.objects.select_related('author__profile').all()
def resolve_thread(self, args, context, info):
id = args.get('id')
if id is not None:
return Thread.objects.get(pk=id)
return None
项目/schema.py:
class Query(project.threads.schema.Query, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query)
如果有人以前使用过这种特殊组合并有任何建议,那就太棒了。
【问题讨论】:
这与石墨烯无关。您要做的是使用连接字段作为根字段。这在 Relay 1 中不受支持,但应该在 Relay 2 中。完整的解释在这里:github.com/facebook/relay/issues/112 我认为这不是真的,我在问题中提到了这一点。石墨烯通过包装所有连接来绕过连接作为根的问题,因此连接成为一个节点,其上有可用的边连接。 我注意到“查询片段”这一行。您是否按照错误提示尝试了 ThreadNodeConnection 上的片段? 【参考方案1】:我遇到了同样的问题,经过长时间的搜索,我终于找到了这个答案 https://github.com/facebook/relay/issues/1558#issuecomment-297010663
由于中继 1 不支持作为根查询的连接。您应该将查看器添加为节点接口来包装您的查询。 因此,在您的服务器主查询(project/schema.py)中,您应该添加以下代码:
class Query(project.threads.schema.Query, graphene.ObjectType):
viewer = graphene.Field(lambda: Query)
id = graphene.ID(required=True)
def resolve_viewer(self, args, context, info):
return info.parent_type
def resolve_id(self, args, context, info):
return 1
class Meta:
interfaces = (graphene.relay.Node,)
现在在你的 graphiql 中,你可以像这样格式化你的查询:
query
viewer
allThreads(first:10)
edges
node
id
在客户端,您可以像这样创建容器:
export default Relay.createContainer(ThreadList,
fragments:
viewer: () => Relay.QL`
fragment on Query
id
allThreads(first:10)
edges
node
id
`,
,
);
希望对你有帮助
【讨论】:
以上是关于石墨烯 Django 和 react-router-relay的主要内容,如果未能解决你的问题,请参考以下文章
石墨烯 django 端点是不是同时需要 X-Csrftoken 和 CsrfCookie?