石墨烯Django和react-router-relay

时间:2017-03-27 23:51:42

标签: django relay graphene-python react-router-relay

我很难找出Graphene Django应该与react-router-relay一起使用的方式。假设我可以通过Django服务器上的GraphiQL控制台使用以下GraphQL查询:

query {
  allThreads {
    edges {
      node {
        id
      }
    }
  }
}

这可能是Graphene使用的commmon viewer包装器的替代品,因为Relay不支持根查询上的连接。所以我理解allThreads实际上是一个节点(ThreadNodeConnection类型),并且有一个我可以查询的边连接。

麻烦的是我无法弄清楚如何在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做错了,但很难知道,因为其他人都使用它来容纳他们的viewer包装器。 GraphQL连接,但Graphene在每个连接上都有一个不同的包装器,所以这可能只适用于我的单一路由,但现在还可以。 Webpack再次喜欢它。但是当我加载页面时,我收到了一个错误的请求&#39;和错误:

  

&#34;片段F1不能作为类型的对象传播到此处   ThreadNodeConnection永远不能是Query&#34;

类型

说实话,那是关于我无法进行的地方,因为我显然不了解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)

如果有人之前使用过这种特殊组合并且有任何建议,那就太棒了。

1 个答案:

答案 0 :(得分:1)

我有同样的问题,经过长时间的搜索,我终于找到了这个答案 https://github.com/facebook/relay/issues/1558#issuecomment-297010663

由于中继1不支持以root查询连接。您应该将查看器作为节点接口来包装您的查询。 因此,在您的服务器主查询(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
               }
            }
          }
      }
    `,
    },
});

我希望这可以帮到你