Joh*_*ron 4 json python-3.x graphene-python
我在python(Flask + Graphene)中有一个后端服务器,我需要返回一个这样的JSON对象:
{
's1': "Section 1",
's2': "Section 2",
's3': "Section 3",
's4': "Section 4"
}
Run Code Online (Sandbox Code Playgroud)
解析器如下所示:
questionnaire = graphene.types.json.JSONString(
description='JSON result test')
def resolve_questionnaire(self, info: graphql.ResolveInfo):
sections = {
's1': "Section 1",
's2': "Section 2",
's3': "Section 3",
's4': "Section 4"
}
print(json.dumps(sections))
return sections
Run Code Online (Sandbox Code Playgroud)
在控制台中我看到了print(json.dumps(sections))我期望的结果:
user-api_1 | {"s1": "Section 1", "s2": "Section 2", "s3": "Section 3", "s4": "Section 4"}
Run Code Online (Sandbox Code Playgroud)
当我更改为时return sections,return json.dumps(sections)我得到如下结果:

问题是如何在石墨烯解析器中正确返回JSON对象? 我知道有像这里使用的json.replace方法,但我相信我只是以错误的方式生成/传递对象.
小智 8
你的初步结果
{
"data": {
"questionnaire": "{\"s1\": \"Section 1\", \"s2\": \"Section 2\", \"s3\": \"Section 3\", \"s4\": \"Section 4\"}"
}
}
Run Code Online (Sandbox Code Playgroud)
是预期的行为.毕竟,questionnaire解析为JSON 字符串.由于它是一个字符串,因此必须双引号,因此必须对其内部引用进行转义.这符合JSON的标准.
要使用该字符串,必须在data.questionnaire对象上运行某种JSON解析器.例如,在javascript中,它会是这样的:
var data;
// Fetching logic to get the data object from your GraphQL server
var sections = JSON.parse(data.questionaire);
// Now you can access its objects
console.log(sections.s1) // Should print "Section 1" on the dev console
Run Code Online (Sandbox Code Playgroud)
然而,如果密钥sections不是预定的(sections.s5可以在一种情况下定义但在另一种情况下未定义),则上述方法并不理想.相反,您可能更愿意拥有一个可以迭代的数组.为此,您必须定义具有显式键值对的"模型".这样做的格式也适用于GraphQL.例如:
import graphene
# Our new model
class Section(graphene.ObjectType):
key = graphene.String() # dictionary key
header = graphene.String() # dictionary value
# Your previous schema with modifications
class Query(graphene.ObjectType):
# questionnaire = graphene.types.json.JSONString(description='JSON result test')
# Return a list of section objects
questionnaire = graphene.List(Section)
def resolve_questionnaire(self, info: graphql.ResolveInfo):
sections = {
's1': "Section 1",
's2': "Section 2",
's3': "Section 3",
's4': "Section 4"
}
sections_as_obj_list = [] # Used to return a list of Section types
# Create a new Section object for each item and append it to list
for key, value in sections.items(): # Use sections.iteritems() in Python2
section = Section(key, value) # Creates a section object where key=key and header=value
sections_as_obj_list.append(section)
# return sections
return sections_as_obj_list
Run Code Online (Sandbox Code Playgroud)
现在,如果我们运行查询:
query {
questionnaire {
key
header
}
}
Run Code Online (Sandbox Code Playgroud)
它返回一个可以迭代的JSON数组.
{
"data" {
"questionnaire": [
{
"key": "s1",
"header": "Section 1"
},
{
"key": "s2",
"header": "Section 2"
},
{
"key": "s3",
"header": "Section 3"
},
{
"key": "s4",
"header": "Section 4"
},
]
}
}
Run Code Online (Sandbox Code Playgroud)
石墨烯现在有一个GenericScalar类型。
from graphene.types import generic
...
errors = generic.GenericScalar()
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以子类化 JSON 类型并替换序列化方法:
class Any(JSON):
@staticmethod
def serialize(dt):
return dt
Run Code Online (Sandbox Code Playgroud)
然后代替
questionnaire = Field(JSON)
Run Code Online (Sandbox Code Playgroud)
写
questionnaire = Field(Any)
Run Code Online (Sandbox Code Playgroud)
是的,这确实打破了 GraphQL 严格类型化的精神,但如果这就是你想要做的,那就是如何去做。请注意,这是仅输出的 hack — 它不允许您接受任意结构作为参数。
| 归档时间: |
|
| 查看次数: |
2421 次 |
| 最近记录: |