python - serialize - json django example
¿Cómo serializas una instancia modelo en Django? (12)
Hay una gran cantidad de documentación sobre cómo serializar un Model QuerySet, pero ¿cómo se serializan en JSON los campos de una instancia de modelo?
¿Qué tal esta manera?
def ins2dic(obj):
SubDic = obj.__dict__
del SubDic[''id'']
del SubDic[''_state'']
return SubDic
o excluya cualquier cosa que no desee.
Aquí está mi solución para esto, que te permite personalizar fácilmente el JSON y organizar registros relacionados
Primero implemente un método en el modelo. Llamo es json
pero puedes llamarlo como quieras, por ejemplo:
class Car(Model):
...
def json(self):
return {
''manufacturer'': self.manufacturer.name,
''model'': self.model,
''colors'': [color.json for color in self.colors.all()],
}
Entonces en la vista que hago:
data = [car.json for car in Car.objects.all()]
return HttpResponse(json.dumps(data), content_type=''application/json; charset=UTF-8'', status=status)
Lista de uso, resolverá el problema
Paso 1:
result=YOUR_MODELE_NAME.objects.values(''PROP1'',''PROP2'').all();
Paso 2:
result=list(result) #after getting data from model convert result to list
Paso 3:
return HttpResponse(json.dumps(result), content_type = "application/json")
No parece que puedas serializar una instancia, tendrías que serializar un QuerySet de un objeto.
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
Me quedo sin la versión svn
de django, por lo que puede no estar en versiones anteriores.
Para evitar el contenedor de matriz, elimínelo antes de devolver la respuesta:
import json
from django.core import serializers
def getObject(request, id):
obj = MyModel.objects.get(pk=id)
data = serializers.serialize(''json'', [obj,])
struct = json.loads(data)
data = json.dumps(struct[0])
return HttpResponse(data, mimetype=''application/json'')
Encontré esta interesante publicación sobre el tema también:
http://timsaylor.com/convert-django-model-instances-to-dictionaries
Utiliza django.forms.models.model_to_dict, que se ve como la herramienta perfecta para el trabajo.
Para serializar y deserializar, use lo siguiente:
from django.core import serializers
serial = serializers.serialize("json", [obj])
...
# .next() pulls the first object out of the generator
# .object retrieves django object the object from the DeserializedObject
obj = serializers.deserialize("json", serial).next().object
Puede usar fácilmente una lista para ajustar el objeto requerido y eso es todo lo que los serializadores de django necesitan para serializarlo correctamente, por ejemplo:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize(''json'', [ obj, ])
Resolví este problema agregando un método de serialización a mi modelo:
def toJSON(self):
import simplejson
return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))
Aquí está el equivalente detallado para aquellos aversos a one-liners:
def toJSON(self):
fields = []
for field in self._meta.fields:
fields.append(field.name)
d = {}
for attr in fields:
d[attr] = getattr(self, attr)
import simplejson
return simplejson.dumps(d)
_meta.fields
es una lista ordenada de campos modelo a los que se puede acceder desde las instancias y desde el propio modelo.
Si está preguntando cómo serializar un único objeto de un modelo y sabe que solo obtendrá un objeto en el conjunto de consulta (por ejemplo, usando objects.get), entonces use algo como:
import django.core.serializers
import django.http
import models
def jsonExample(request,poll_id):
s = django.core.serializers.serialize(''json'',[models.Poll.objects.get(id=poll_id)])
# s is a string with [] around it, so strip them off
o=s.strip("[]")
return django.http.HttpResponse(o, mimetype="application/json")
que te daría algo de la forma:
{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What''s up?"}}
Si está tratando con una lista de instancias de modelo, lo mejor que puede hacer es usar serializers.serialize()
, que se adaptará perfectamente a sus necesidades.
Sin embargo, debe enfrentar un problema al tratar de serializar un solo objeto, no una list
de objetos. De esta forma, para deshacerse de diferentes hacks, simplemente use el model_to_dict
de Django (si no me equivoco, serializers.serialize()
basa en él):
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Ahora solo necesitas una llamada directa de json.dumps
para serializarla en json:
import json
serialized = json.dumps(dict_obj)
¡Eso es! :)
Suena como si lo que preguntase implica serializar la estructura de datos de una instancia de modelo de Django para la interoperabilidad. Los otros carteles son correctos: si quieres que el formulario serializado se use con una aplicación de Python que pueda consultar la base de datos a través de la API de Django, querrás serializar un conjunto de consulta con un objeto. Si, por otro lado, lo que necesita es una forma de volver a inflar la instancia del modelo en otro lugar sin tocar la base de datos o sin usar Django, entonces tiene un poco de trabajo por hacer.
Esto es lo que hago:
Primero, uso demjson
para la conversión. Resultó ser lo primero que encontré, pero podría no ser el mejor. Mi implementación depende de una de sus características, pero debería haber formas similares con otros convertidores.
En segundo lugar, implemente un método json_equivalent
en todos los modelos que necesite serializar. Este es un método mágico para demjson
, pero es probable que sea algo en lo que quieras pensar independientemente de la implementación que elijas. La idea es devolver un objeto directamente convertible en json
(es decir, una matriz o diccionario). Si realmente quieres hacer esto automáticamente:
def json_equivalent(self):
dictionary = {}
for field in self._meta.get_all_field_names()
dictionary[field] = self.__getattribute__(field)
return dictionary
Esto no será útil para usted a menos que tenga una estructura de datos completamente plana (sin ForeignKeys
, solo números y cadenas en la base de datos, etc.). De lo contrario, deberías pensar seriamente sobre la forma correcta de implementar este método.
En tercer lugar, llame a demjson.JSON.encode(instance)
y tiene lo que desea.
ville = UneVille.objects.get(nom=''lihlihlihlih'')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Devuelvo el dict de mi instancia
por lo que devuelve algo como {''campo1'': valor, "campo2": valor, ....}