摆脱JSON中的Mongo $标志

时间:2015-08-09 12:03:34

标签: json mongodb flask python-3.4 flask-mongoengine

我正在使用MongoDB为SPA(Angular)构建python后端。

以下是我使用的内容:Python 3.4MongoDB 3Flaskflask-mongoengineflask-restful

现在我从后端收到以下JSON:

[
    {
        "_id": {
            "$oid": "55c737029380f82fbf52eec3"
        },
        "created_at": {
            "$date": 1439129906376
        },
        "desc": "Description.....",
        "title": "This is title"
    },
    etc...
]

我希望收到类似的内容

[
    {
        "_id": "55c737029380f82fbf52eec3",
        "created_at": 1439129906376,
        "desc": "Description.....",
        "title": "This is title"
    },
    etc...
]

我现在的代码:

from flask import json
from vinnie import app
from flask_restful import Resource, Api
from vinnie.models.movie import Movie

api = Api(app)

class Movies(Resource):
    def get(self):
        movies = json.loads(Movie.objects().all().to_json())
        return movies

api.add_resource(Movies, '/movies')

型号:

import datetime
from vinnie import db

class Movie(db.Document):
    created_at = db.DateTimeField(default=datetime.datetime.now, required=True)
    title = db.StringField(max_length=255, required=True)
    desc = db.StringField(required=True)

    def __unicode__(self):
        return self.title

为前端格式化方便的JSON的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

如果您确信想要摆脱所有类似的情况,那么您当然可以编写与该模式匹配的代码。例如:

info = [
    {
        "_id": {
            "$oid": "55c737029380f82fbf52eec3"
        },
        "created_at": {
            "$date": 1439129906376
        },
        "desc": "Description.....",
        "title": "This is title"
    },
    #etc...
]

def fix_array(info):
    ''' Change out dict items in the following case:
           - dict value is another dict
           - the sub-dictionary only has one entry
           - the key in the subdictionary starts with '$'
        In this specific case, one level of indirection
        is removed, and the dict value is replaced with
        the sub-dict value.
    '''
    for item in info:
        for key, value in item.items():
            if not isinstance(value, dict) or len(value) != 1:
                continue
            (subkey, subvalue), = value.items()
            if not subkey.startswith('$'):
                continue
            item[key] = subvalue

fix_array(info)
print(info)

这将返回:

[{'title': 'This is title', 'created_at': 1439129906376, 'desc': 'Description.....', '_id': '55c737029380f82fbf52eec3'}]

显然,使用JSON重新格式化它是微不足道的。

答案 1 :(得分:1)

我在flask-restful扩展程序中找到了一个解决我问题的简洁解决方案。

它提供fields模块。

  

Flask-RESTful提供了一种简单的方法来控制您在响应中实际呈现的数据。使用fields模块,您可以在资源中使用所需的任何对象(ORM模型/自定义类等)。字段还允许您格式化和过滤响应,因此您不必担心公开内部数据结构。

     

在查看代码时,还会非常清楚将呈现哪些数据以及如何格式化数据。

示例:

from flask_restful import Resource, fields, marshal_with

resource_fields = {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
}

class Todo(Resource):
    @marshal_with(resource_fields, envelope='resource')
    def get(self, **kwargs):
        return db_get_todo()  # Some function that queries the db

Flask-RESTful Output Fields Documentation