2011-05-27 17 views
6

Así que estoy tratando de devolver un objeto JSON para un proyecto. He pasado unas horas intentando que Django devuelva el JSON.¿No se puede devolver el objeto JSON utilizando MongoEngine Pymongo con Django?

Aquí está la opinión de que hemos estado trabajando con:

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) 

Aquí es mi modelo:

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 

Esto es lo que está regresando:

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

Alguna idea sobre cómo ¿Puedo devolver el JSON?

Respuesta

8

simplejson.dumps() no sabe cómo "alcanzar" sus objetos personalizados; la función default, json_util.default debe llamar a str() o repr() en sus documentos. (Es json_util código personalizado que ha escrito? Si es así, mostrar su origen aquí podría probar mi reclamación.)

En última instancia, su función default deberá ser capaz de dar sentido a los documentos MongoEngine. Puedo pensar en por lo menos dos maneras de que esto podría ser implementado:

  1. escribir una función personalizada default que funcione para todos los documentos MongoEngine por introspección de su _fields atributo (aunque tenga en cuenta que el subrayado inicial significa que esto es parte de el detalle API/aplicación privada de MongoEngine y puede estar sujeto a cambios en futuras versiones)

  2. que cada uno de sus documentos implementar un método as_dict que devuelve una representación diccionario del objeto. Esto funcionaría de manera similar al método to_mongo provisto en documentos por MongoEngine, pero no debería devolver los campos _types o _cls (nuevamente, estos son detalles de implementación de MongoEngine).

me gustaría sugerir que vaya con la opción # 2: el código será más limpio y más fácil de leer, mejor encapsulado, y no requerirá el uso de las APIs privadas.

4

Como dcrosta sugirió que puede hacer algo como esto, espero que eso lo ayude.

definición de documento

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

Con MongoEngine 0,8 o mayor, objetos y QuerySets tienen un método to_json().

>>> User.objects.to_json() 
Cuestiones relacionadas