JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与(2)

这就是在遇到问题是只着眼解决眼前错误导致后续一连串改动所带来的弊病。我们沿着上面 JSON 变换的链条向上追溯,看有没有更好的解决方案。很简单, 遵循传统规则,出现特例的时候,改变自身适应规则,而不是改变规则 :

# Handler async def post(self): user = await self.db.user.find_one({}) user['_id'] = str(user['_id']) self.write(user)

当然,如果是多条数据的列表形式,还需要进一步改造:

# DB async def get_top_users(self, n = 20): users = [] async for user in self.db.user.find({}).sort('rank', -1).limit(n): user['_id'] = str(user['_id']) users.append(user) return users

4. Python <=> HTML+Riot.js

如果上面的问题可以通过 遵守规则 来解决,那么接下来这个问题就是一个挑战规则的故事。除去 Ajax 动态加载部分,网页上的其他数据是通过后端模板引擎渲染得来的,也就是说是 Hard-coding 为 HTML 的。在浏览器加载并解析这个 HTML 文件之前它们只是纯文本文件,而我们需要的是直接将数据塞仅 <script> 标签在浏览器运行 JavaScript 时直接可用。严格意义上来说这并不算是 JSON 的应用,而是 Python 的 dict 与 JavaScript 的 Object 之间的直接转换,常规的方法应该这样写:

# Handler async def get(self): users = self.db.get_top_users() render_data = dict( users = users ) self.render('users.html', **render_data) <!-- HTML + Riot.js --> <app></app> <script> riot.mount('app', { users: [ {% for user in users %} { name: "{{ user['name']}}", is_admin: "{{ user['is_admin']}}" }, {% end %} ], }) </script>

这样写是对的,但是要解决上面提到的 ObjectId() 问题还是需要一些额外的处理(尤其是引号问题)。另外为了解决 ObjectId 的问题我还尝试了一种比较蠢的方法(在上面的 JSON.parse 遇到错误之前):

# Handler async def get(self): users = self.db.get_top_users() render_data = dict( users = JSONEncoder.encode(users) ) self.render('users.html', **render_data) <!-- HTML + Riot.js --> <app></app> <script> riot.mount('app', { users: JSON.parse('{{ users }}'), }) </script>

其实跟第 3 小节的问题一样,模板引擎渲染过程与 HTTP 传输过程是类似的,不同的是在模板中字符串变量就是纯粹的值(没有引号),因此完全可以用生成 JavaScript 脚本文件的形式渲染变量而无需顾虑特殊字符(下面的 {% raw ... %} 是 Tornado 模板用于防止特殊符号被 HTML 编码的语法):

<!-- HTML + Riot.js --> <app></app> <script> riot.mount('app', { users: {% raw users %}), }) </script>

总结

JSON 是很好用的数据格式,但是在不同语言环境之间切换还是有很多细节问题需要注意。此外, 遵循传统规则,出现特例的时候,改变自身适应规则,而不是试图改变规则 ,这一条不一定适应所有问题,但对于那些已被公认的规则,请勿轻易挑战。

以上所述是小编给大家介绍的JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax的相关知识,希望对大家有所帮助,如果大家想了解更多资讯敬请关注脚本之家网站!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzpfjd.html