Не можете вернуть объект JSON, используя MongoEngine Pymongo с Django? - PullRequest
6 голосов
/ 27 мая 2011

Итак, я пытаюсь вернуть объект JSON для проекта.Я потратил несколько часов, пытаясь заставить Джанго просто вернуть JSON.

Вот мнение, с которым мы работали:

def json(request, first_name):
    user = User.objects.all()
    #user = User.objects.all().values()
    result = simplejson.dumps(user, default=json_util.default)
    return HttpResponse(result)

Вот моя модель:

class User(Document):  
    gender = StringField( choices=['male', 'female', 'Unknown']) 
    age = IntField()
    email = EmailField()
    display_name = StringField(max_length=50)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)
    location = StringField(max_length=50)
    status = StringField(max_length=50)
    hideStatus = BooleanField()
    photos = ListField(EmbeddedDocumentField('Photo')) 
    profile =ListField(EmbeddedDocumentField('ProfileItem'))
    allProfile = ListField(EmbeddedDocumentField('ProfileItem')) #only return for your own profile

Вот что он возвращает:

[<User: User object>, <User: User object>] is not JSON serializable

Есть мысли о том, как я могу просто вернуть JSON?

Ответы [ 3 ]

10 голосов
/ 31 мая 2013

При использовании MongoEngine 0.8 или выше объекты и наборы запросов имеют метод to_json().

>>> User.objects.to_json()
8 голосов
/ 08 июня 2011

simplejson.dumps() не знает, как "добраться до" ваших пользовательских объектов; функция default, json_util.default должна просто вызывать str() или repr() в ваших документах. (Является ли json_util пользовательский код, который вы написали? Если это так, то указание его источника может подтвердить мое утверждение.)

В конечном счете, ваша функция default должна иметь возможность разобраться в документах MongoEngine. Я могу придумать как минимум два способа, которыми это может быть реализовано:

  1. Напишите пользовательскую функцию default, которая работает для всех документов MongoEngine, анализируя их атрибут _fields (хотя обратите внимание на то, что нижнее подчеркивание означает, что это часть частного API / детали реализации MongoEngine и Возможны изменения в следующих версиях)

  2. Пусть каждый из ваших документов реализует метод as_dict, который возвращает словарное представление объекта. Это будет работать аналогично методу to_mongo, предоставленному в документах MongoEngine, но не должно возвращать поля _types или _cls (опять же, это детали реализации MongoEngine).

Я бы посоветовал вам воспользоваться вариантом № 2: код будет чище и проще для чтения, лучше инкапсулирован и не потребует использования каких-либо частных API.

4 голосов
/ 31 августа 2012

Как предположил dcrosta, вы можете сделать что-то подобное, надеюсь, это поможет вам.

Определение документа

class MyDocument(Document):
    # Your document definition

    def to_dict(self):
        return mongo_to_dict_helper(self)

helper.py:

from mongoengine import StringField, ListField, IntField, FloatField

def mongo_to_dict_helper(obj):
    return_data = []
    for field_name in obj._fields:
        if field_name in ("id",):
            continue

        data = obj._data[field_name]

        if isinstance(obj._fields[field_name], StringField):
            return_data.append((field_name, str(data)))
        elif isinstance(obj._fields[field_name], FloatField):
            return_data.append((field_name, float(data)))
        elif isinstance(obj._fields[field_name], IntField):
            return_data.append((field_name, int(data)))
        elif isinstance(obj._fields[field_name], ListField):
            return_data.append((field_name, data))
        else:
            # You can define your logic for returning elements
    return dict(return_data)
...