我试图从应用引擎中的数据存储区发送10条最新帖子。
这是数据库:
class Author(ndb.Model):
"""Sub model for representing an author."""
identity = ndb.StringProperty(indexed=False)
email = ndb.StringProperty(indexed=True)
class Message(ndb.Model):
"""A main model for representing an individual Message entry."""
author = ndb.StructuredProperty(Author)
content = ndb.StringProperty(indexed=False)
date = ndb.DateTimeProperty(auto_now_add=True)
这是代码:
class Query(webapp2.RequestHandler):
def post(self):
message_name = self.request.get('db_name',
DEFAULT_KEY)
message_query = Message.query(ancestor=db_key(
message_name)).order(-Message.date)
messages = message_query.fetch(10)
items = []
for message in message_query:
items.append({'id': message.author.identity,
'email':message.author.email,
'content':message.content,
'date':message.date})
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps(items))
错误信息:
TypeError: datetime.datetime(2015, 3, 21, 15, 43, 58, 248650) is not JSON serializable
为什么不能让JSON返回该格式的日期? 我如何将其重新格式化为正确的JSON格式?
溴
答案 0 :(得分:5)
我建议不要重新发明轮子,而是建议在https://gist.github.com/erichiggins/8969259安装和使用ndb_json.py模块 - 它代表你强有力地优雅地处理各种潜在的陷阱和陷阱。然后,ndb_json.dumps
就是你所需要的。
请注意,您发布的代码中有一个特殊的异常......:
message_query = Message.query(ancestor=db_key(
message_name)).order(-Message.date)
messages = message_query.fetch(10)
items = []
for message in message_query:
items.append(...)
这会将最新的10条消息提取到messages
列表中,然后您完全忽略它!然后所有较旧的消息(来自查询的循环)都会被放入{{ 1}}无限数字。我怀疑这实际上是你想要的 - 也许你的意思是items
:
for
序列化到响应"只是最新的10条消息"而不是"所有消息除了最新的10"这是你的代码所做的。
所以,如果是这种情况,我建议您使用模块避免 for message in messages:
items.append(...)
"建立items
"部分,只需替换
self.response.out.write(json.dumps(items))
与
self.response.write(ndb_json.dumps(messages))
(另请注意,out
部分是遗留工件/黑客,用于向后兼容古代版本的webapp
,最好不在新应用中使用 - 与您的Q没有直接关系,但只是就像我认为的那样,你可能会在序列化"其余的查询"而不是"最新的10条消息"中出现的错误,希望对你有所帮助! - )
答案 1 :(得分:1)
JSON对datetime对象一无所知。这取决于您想要的时间以及以后的时间。我建议你将它转换为unix时间戳,这只是一个整数,因此是JSON可序列化的。
这是一篇文章,其中描述了所有python版本的datetime对象到整数的转换:Converting datetime.date to UTC timestamp in Python
答案 2 :(得分:1)
您可以扩展JSONEncoder类来处理任何对象类型,如下所示:
from datetime import datetime
import json
class MyJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
# format however you like/need
return obj.strftime("%Y-%m-%d")
# pass any other unknown types to the base class handler, probably
# to raise a TypeError.
return json.JSONEncoder.default(self, obj)
objDict = {"str":"foo", "int":212, "date":datetime.today()}
print json.dumps(objDict, cls=MyJsonEncoder)
{"int": 212, "date": "2015-03-21", "str": "foo"}