2011-05-27 136 views
6

所以我试图返回一个项目的JSON对象。我花了几个小时试图让Django刚刚返回JSON。使用MongoEngine Pymongo与Django无法返回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?

回答

8

simplejson.dumps()不知道如何“接触”您的自定义对象; default函数json_util.default必须在文档上调用str()repr()。 (是你写的吗?如果是这样,这里显示出它的来源可以证明我的要求json_util自定义代码。)

最终,你default功能将需要能够使MongoEngine文件的意义。我能想到的至少有两种方式,这可能实现:

  1. 编写自定义default功能,通过反省自己_fields属性(所有MongoEngine文件工作但要注意的是,前面的下划线表示这是部分MongoEngine的私有API /实现细节,可能会在将来的版本中改变)

  2. 让每个文档的实现方法as_dict返回对象的字典中表示。这与MongoEngine在文档中提供的to_mongo方法类似,但不应返回_types_cls字段(同样,这些是MongoEngine的实现细节)。

我建议你去与选项#2:代码将是更清洁和更容易阅读,更好的封装,并且不需要使用任何私有的API。

4

由于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) 
10

随着MongoEngine 0.8或更大,目的和查询集具有to_json()方法。

>>> User.objects.to_json()