【问题标题】:Graphene Django "Must provide query string"石墨烯 Django“必须提供查询字符串”
【发布时间】:2017-10-26 09:07:47
【问题描述】:

我已经使用 Django 设置了一个 Graphene 服务器。当我通过 GraphiQL(网络客户端)运行查询时,一切正常。但是,当我从其他任何地方运行时,我会收到错误消息:“必须提供查询字符串。”

我做了一些故障排除。 GraphiQL 使用Content-Type: application/json 将 POST 数据发送到 GraphQL 服务器。这是我从 GraphiQL 的 Chrome 网络选项卡复制的请求正文:

{"query":"query PartnersQuery {\n  partners{\n    name\n    url\n    logo\n  }\n}","variables":"null","operationName":"PartnersQuery"}

当我使用Content-Type: application/json 将其复制到 Postman 时,我得到以下响应:

{
  "errors": [
    {
      "message": "Must provide query string."
    }
  ]
}

此问题的原因可能是什么?我没有对架构做过任何疯狂的事情。只是按照石墨烯文档中的教程进行操作。还有什么可能导致这样的问题?

【问题讨论】:

    标签: django graphql graphene-python


    【解决方案1】:

    在 django 上启用 graphine

      url(r'^graphql', csrf_exempt(GraphQLView.as_view(graphiql=settings.DEBUG))),
    

    执行一些查询并查看它是否有效

    在 Chrome 浏览器上,转到 graphiQL 端点:http://localhost:8000/graphql? 打开“开发者工具”浏览器并转到“网络”标签。

    再次执行您的查询。现在它出现在请求列表中。现在鼠标右键单击它并复制它“copy as CURL”。现在您可以将其复制粘贴到安装了 curl 的 linux 终端。或者就像您的情况一样,您可以尝试扣除那里的内容,并尝试在您的 IDE 中重用它,例如 Insomnia 或 Postman 等客户端。例如,您可能会发现与 graphiQL enpoint 上的会话一起使用的授权最终不是您想要的...

    curl 'http://localhost:8000/graphql?' -H 'Origin: http://localhost:8000' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9,pl;q=0.8,de;q=0.7' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Cookie: _ga=GA1.1.1578283610.1528109563; _gid=GA1.1.920024733.1541592686; csrftoken=EGBeegFoyMVl8j1fQbuEBG587nOFP2INwv7Q0Ee6HeHHmsLOPUwRonzun9Y6pOjV; sessionid=4u9vngcnmjh927a9avpssvc4oq9qyqoe' -H 'Connection: keep-alive' -H 'X-CSRFToken: EGBeegFoyMVl8j1fQbuEBG587nOFP2INwv7Q0Ee6HeHHmsLOPUwRonzun9Y6pOjV' --data-binary '{"query":"{\n  allStatistics(projectId: 413581, first:25) {\n    pageInfo {\n      startCursor\n      endCursor\n      hasPreviousPage\n      hasNextPage\n    }\n    edges {\n      cursor\n      node {\n        id\n        clickouts\n        commissionCanc\n        commissionConf\n        commissionLeads\n        commissionOpen\n        eventDate\n        extractTstamp\n        hash\n        leads\n        pageviews\n        projectId\n        transactionsCanc\n        transactionsConf\n        transactionsOpen\n      }\n    }\n  }\n}\n","variables":null,"operationName":null}' --compressed
    

    【讨论】:

      【解决方案2】:

      当我尝试使用POSTMAN 使用graphQl 查询时,我遇到了同样的问题, 在 POSTMAN 中使用 json 类型在 row 中发送数据。 您必须像这样进行json数据grapQl查询和突变数据

      查询命令:

      {"query":"{user(id:902){id,username,DOB}}"}
      

      变异命令:

      { "query": "mutation {createMutations(reviewer:36, comments:\"hello\",loan: 1659, approved: true ){id}}" }
      
             #commnent: String Type
             #data_id:Int Type
             #approved:Boolean Type
      

      【讨论】:

        【解决方案3】:

        我的代码中的问题是我为 graphQL 设置了不正确的 URL。我有以下内容:

        url(r'^graphql/', GraphQLView.as_view())
        

        正斜杠有很大的不同。删除它解决了问题。正确的做法是:

        url(r'^graphql', GraphQLView.as_view())
        

        【讨论】:

        • 试试 ^graphql/$ 让它捕获 URL 中的所有内容
        【解决方案4】:

        我遇到了与原始发帖人 Gasim 完全相同的问题。研究“graphiql.html”中的代码,我发现他们正在将进入 body 的查询字符串转换为 URL 中的查询参数。因此,您最终会通过 Postman 发送此 URL:

        http://127.0.0.1:8000/graphql?query=%7B%0A%20%20allCategories%20%7B%0A%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20name%0A%20%20%20%20%20%20%20%20ingredients%20%7B%0A%20%20%20%20%20%20%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A

        在我看来,在 URL 的查询字符串中精确复制 body 中的内容似乎是荒谬的,但这似乎是让 Graphene 服务器返回有效响应的唯一方法。

        确定这是一个需要修复的错误/缺点吗?

        罗伯特

        【讨论】:

          【解决方案5】:

          以下是我如何使用带有简单突变的石墨烯 Django 后端从 Postman 获得成功的响应:

          1. 将方法设置为 POST
          2. 将 URL 添加到您的 graphQL 端点,例如http://localhost:8000/api/
          3. 添加一个header——key:“Content-Type”,value:“application/json”
          4. 将正文设置为“原始”
          5. 将查询粘贴到正文窗口中,例如{"query":"{myModels {id}}","variables":"null","operationName":null}

          这听起来很像你所做的,所以你一定很接近。

          【讨论】:

            【解决方案6】:

            parse_body 无法解析传入数据时会引发此错误。我会先查看传递给此方法的数据并确保其类型正确。

            例如,multipart/form-data 部分天真地返回 request.POST,可能需要将其覆盖以处理,例如,apollo-upload-client 发送的用于文件上传处理的请求。 在我们的例子中,我们创建了一个既需要登录又支持 apollo-upload-client 用例的视图,它工作正常。

            【讨论】:

            • 嗨@adam-donahue,您能否展示您的自定义parse_body 函数的实现以及如何覆盖此方法。你几乎把我指向了我整天调查的问题。对于身份验证,我使用来自rest_frameworkauthentication_classes 装饰器附加了一个自定义TokenAuthentication 类。不知道从哪里开始操作parse_body。你能指出我正确的方向吗?
            • github.com/graphql-python/graphene-django/issues/404 好的,我在这里找到了一个解决方案:)
            【解决方案7】:

            查看示例应用,看看它们是如何工作的,

            例如 https://github.com/mjtamlyn/graphene-tutorial 他们执行以下操作:

            from django.views.decorators.csrf import csrf_exempt
            from graphene_django.views import GraphQLView
            
            url(r'^explore', GraphQLView.as_view(graphiql=True)),
            url(r'^graphql', csrf_exempt(GraphQLView.as_view())),
            

            【讨论】:

              猜你喜欢
              • 2020-01-27
              • 2020-09-03
              • 2020-08-11
              • 2019-12-08
              • 2020-07-27
              • 2019-01-16
              • 2018-01-13
              • 1970-01-01
              • 2018-01-11
              相关资源
              最近更新 更多