2011-05-27 131 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()