Python Namedtuple未在Flask中正确呈现
我正在使用Flask/Python应用程序,并且在jinja模板中呈现namedtuple类型数据时面临问题 我正在使用版本Python Namedtuple未在Flask中正确呈现,python,flask,jinja2,Python,Flask,Jinja2,我正在使用Flask/Python应用程序,并且在jinja模板中呈现namedtuple类型数据时面临问题 我正在使用版本 Python 3.6 烧瓶1.1.2 Jinja2 3.0.1 下面是我的工作示例代码: from collections import namedtuple from flask import Flask, render_template, render_template_string # .... app = Flask(__name__) Category
- Python 3.6
- 烧瓶1.1.2
- Jinja2 3.0.1
from collections import namedtuple
from flask import Flask, render_template, render_template_string
# ....
app = Flask(__name__)
Category = namedtuple(
'Category',
['name', 'priority', 'menus', 'has_next_level']
)
MenuItem = namedtuple(
'MenuItem',
['title', 'url', 'target', 'id', 'parent_id', 'object_type']
)
# --- Sample input value render_template()
menu_content = {
50: {
'AGENTS': Category(
name='AGENTS',
priority=1,
menus=[
MenuItem(
title='Agent2',
url='/monitoring/dashboard/6/agent/2',
target=None,
id=2,
parent_id=None,
object_type='agent'
),
MenuItem(
title='Postgres Enterprise Manager Host',
url='/monitoring/dashboard/6/agent/1',
target=None,
id=1,
parent_id=None,
object_type='agent'
)],
has_next_level=True
)
}
}
output = None
with app.app_context():
output = render_template_string(
'{{ menu_content|tojson|safe }}',
menu_content=menu_content
)
print(output)
输出,我得到:
{“50”:{“AGENTS”:[“AGENTS”,1,[[“Agent2”,“/monitoring/dashboard/6/agent/2”,null,2,null,“agent”],[“Postgres Enterprise Manager Host”,“/monitoring/dashboard/6/agent/1”,null,1,null,“agent”]],true]
预期产出:
{“50”:{“代理”:{“has_next_level”:true,“menu”:[{“id”:2,“object_type”:“代理”,“parent_id”:null,“target”:null,“title”:“Agent2”,“url”:“/monitoring/dashboard/6/agent/2”},{“id”:1,“object_type”:“代理”,“parent_id”:null,“target”:null,“title”:“Postgres Enterprise Manager主机”,“url”:“/monitoring/dashboard/6/agent/1”}
我遗漏了什么吗?感谢您为您的问题添加了详细信息,以便我可以重现您的问题
{"50":
{"AGENTS":
{"name": "AGENTS",
"priority": 1,
"menus": [
{"title": "Agent2", "url": "/monitoring/dashboard/6/agent/2", "target": null, "id": 2, "parent_id": null, "object_type": "agent"},
{"title": "Postgres Enterprise Manager Host", "url": "/monitoring/dashboard/6/agent/1", "target": null, "id": 1, "parent_id": null, "object_type": "agent"}],
"has_next_level": true
}
}
}
通过调用json.dumps
您将得到一个json字符串。如果您只使用namedtuple\u asdict
您将得到一个OrderedDict
说明:
主要问题是,json.jsonecoder
(参见此处的转换表:)默认不支持要JSONify的对象
首先,对象menu content
是dict
的dict
的namedtuple
其次,这个namedtuple
包含一个str
、一个int
、一个list
和一个bool
第三,list
包含2个namedtuple
s
因此,我们必须找到一种方法来说明如何正确地将这种类型的结构转换为JSON
我们可以扩展json.jsonecoder
(比如docs()中的ComplexEncoder
示例),或者创建一个函数来处理这个问题
在这里,我们使用的函数将检测每个对象的类型,并对其进行转换,以获得正确的结果
此函数的功劳归@mistermiagi所有,他在此处发布了此函数:。
我刚刚对Python3做了一些修改
您注意到您的namedtuple
s被转换为list
:这是因为json.jsonecoder
(参见上面的链接)使用的转换表告诉您将Python的list
s和tuple
转换为json数组
而namedtuple
是tuple
的一个子类,因此您的namedtuple
将转换为JSON数组
示例:
menu_item = MenuItem(
title='Agent2',
url='url2',
target=None,
id=2,
parent_id=None,
object_type='agent'
)
menu_item_json_dumps = json.dumps(menu_item)
print(menu_item_json_dumps)
# OUTPUT: ["Agent2", "url2", null, 2, null, "agent"]
menu_item_as_dict_json_dumps = json.dumps(menu_item._asdict())
print(menu_item_as_dict_json_dumps)
# OUTPUT: {"title": "Agent2", "url": "url2", "target": null, "id": 2, "parent_id": null, "object_type": "agent"}
您可以在@martineau-answer中找到更多信息:
调用上述函数将在需要时调用asdict()。
您可以调整它,以便跳过一些无值或其他任何内容。可能的答案:。解决方法(可能不是100%满意):您可以使用
\u asdict
的namedtuple
方法。这是否回答了您的问题?@Rivers我的虚拟电视中有simplejson,但我仍然得到了一个数组。
menu_item = MenuItem(
title='Agent2',
url='url2',
target=None,
id=2,
parent_id=None,
object_type='agent'
)
menu_item_json_dumps = json.dumps(menu_item)
print(menu_item_json_dumps)
# OUTPUT: ["Agent2", "url2", null, 2, null, "agent"]
menu_item_as_dict_json_dumps = json.dumps(menu_item._asdict())
print(menu_item_as_dict_json_dumps)
# OUTPUT: {"title": "Agent2", "url": "url2", "target": null, "id": 2, "parent_id": null, "object_type": "agent"}