Python Pyramid неправильно отображает JSON

Я использую метод to_json MongoEngine для объекта, который я хочу отобразить на странице Pyarmid с визуализацией json. Я сделал много JSON-рендеринга в Pyramid, но не в MongoEngine. Метод MongoEngine to_json просто вызывает json_util.dumps. Все это прекрасно работает в Python. Проблема в том, что когда Pyramid рендерит страницу, она рендерится так:

{
  "0": "\"",
  "1": "{",
  "2": "\\",
  "3": "\"",
  "4": "_",  etc...

Однако дамп json выглядит нормально в Python, прежде чем он будет отображен:

'{"_id": {"$oid": "4ebca43ccc7a67085b000000"}, "created": {"$date": 1346419407715}, "modified": {"$date": 1403757381829}, "modified_by": {"$oid": "4ebca43ccc7a67085b000000"}, "email":  etc...

Как было предложено в комментариях, кажется, что json обрабатывается более одного раза, но я не могу понять, где.

Я беру объект User из базы данных и прикрепляю его к каждому запросу:

def get_user(request):
    return User.objects(id=ObjectId(authenticated_userid(request))).first()

config.add_request_method(get_user, 'user', reify=True)

Я возвращаю пользователя по запросу:

@view_config(route_name='api.user', permission='authenticated', renderer='json')
def user_vc(request):
    response = request.response
    _id = request.matchdict['id']
    if _id == 'session':
        user = request.user
        if not user:
            response.status = 403
            return response
        else:
            print user  # user object as expected (not json)
            return user

У меня есть собственный адаптер для обработки объекта User:

# custom json adapters
custom_json = JSON()

def user_adapter(obj, request):
    print obj.to_json()  # the json looks ok here
    return obj.to_json()
custom_json.add_adapter(User, user_adapter)

config.add_renderer('json', custom_json)

Я сам не делаю никакой другой jsonification, кроме адаптера выше. Так что такое?? Любая помощь будет здорово.


person MFB    schedule 26.06.2014    source источник
comment
Совершенно ясно, что вы много раз сонифицируете свои данные. Пирамида отображает страницу так, как будто Javascript итерирует строковый объект.   -  person Antti Haapala    schedule 26.06.2014
comment
В любом случае вам необходимо добавить соответствующий код в свой вопрос в соответствии с рекомендациями!   -  person Antti Haapala    schedule 26.06.2014
comment
Спасибо @AntiHaapala. Я добавил соответствующий код, согласно вашему хорошему предложению.   -  person MFB    schedule 26.06.2014
comment
В Pyramid уже есть встроенный JSON-рендерер. Есть ли причина для определения вашего собственного пользовательского? Ваше представление уже настроено на использование средства визуализации json, поэтому пропустите определение своего пользовательского средства визуализации и просто верните словарь. Pyramid позаботится о преобразовании словаря в JSON.   -  person Pedro Romano    schedule 26.06.2014
comment
Адаптер должен возвращать структуру данных Python, а не строку.   -  person Antti Haapala    schedule 26.06.2014
comment
@PedroRomano Конечно. Но гораздо эффективнее создать собственный рендерер для пользовательских объектов, которые Pyramid не декодирует изначально, чем преобразовывать объект каждый раз, когда он возвращается. Я думаю, именно поэтому в Pyramid существует возможность создавать собственные рендереры.   -  person MFB    schedule 27.06.2014


Ответы (1)


Благодаря комментарию @AnttiHappala выше я обнаружил проблему. Метод to_json MongoEngine преобразует объекты в строку jsonified. Однако Пирамиде нужна структура данных json. Итак, чтобы исправить это, я добавил следующую функцию в свой пользовательский рендерер:

def render_to_json(obj):
        return json.loads(obj.to_json())

    def user_adapter(obj, request):
        return render_to_json(obj)
    custom_json.add_adapter(User, user_adapter)

Теперь я могу добавить собственный рендерер для других моих объектов MongoEngine и вернуть их изначально.

person MFB    schedule 26.06.2014