Hay mucha documentación sobre cómo serializar un Model QuerySet, pero ¿cómo se serializa a JSON los campos de una instancia de modelo?
Hay mucha documentación sobre cómo serializar un Model QuerySet, pero ¿cómo se serializa a JSON los campos de una instancia de modelo?
Respuestas:
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, ])
[0]
al final de tu última línea, como sugirió @DavorLucic? Y no hay necesidad de una coma final en su lista literal (por amor a PEP8;).
Si se trata de una lista de instancias de modelo, lo mejor que puede hacer es usarla serializers.serialize()
, se ajustará perfectamente a su necesidad.
Sin embargo, debe enfrentar un problema al intentar serializar un solo objeto, no uno list
de los objetos. De esa manera, para deshacerte de diferentes hacks, solo usa Django model_to_dict
(si no me equivoco, serializers.serialize()
confía en él también):
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Ahora solo necesita una json.dumps
llamada directa para serializarlo a json:
import json
serialized = json.dumps(dict_obj)
¡Eso es! :)
datetime
campos. Lo resolvió de esta manera json.loads(serialize('json', [obj]))[0]
mientras el serializador esdjango.core.serializers.serialize
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')
También encontré esta publicación interesante sobre el tema:
http://timsaylor.com/convert-django-model-instances-to-dictionaries
Utiliza django.forms.models.model_to_dict, que parece la herramienta perfecta para el trabajo.
Hay una buena respuesta para esto y me sorprende que no se haya mencionado. Con unas pocas líneas puedes manejar fechas, modelos y todo lo demás.
Cree un codificador personalizado que pueda manejar modelos:
from django.forms import model_to_dict
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Model
class ExtendedEncoder(DjangoJSONEncoder):
def default(self, o):
if isinstance(o, Model):
return model_to_dict(o)
return super().default(o)
Ahora úselo cuando use json.dumps
json.dumps(data, cls=ExtendedEncoder)
Ahora los modelos, las fechas y todo se pueden serializar y no tiene que estar en una matriz o serializado y sin serializar. Todo lo que tenga personalizado puede agregarse al default
método.
Incluso puede usar la respuesta Json nativa de Django de esta manera:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
y json.dump
métodos. De esta manera, no necesita cambiar el flujo de trabajo de la aplicación porque usa objetos personalizados o agrega otro método de llamada antes de convertir a json. Simplemente agregue su código de conversión en el codificador y estará listo para comenzar.
Parece que lo que está preguntando implica la serialización de la estructura de datos de una instancia del modelo Django para la interoperabilidad. Los otros carteles son correctos: si desea que el formulario serializado se use con una aplicación de Python que puede consultar la base de datos a través de la API de Django, entonces desea serializar un conjunto de consultas 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 que encontré primero, 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.
Segundo, implemente un json_equivalent
método en todos los modelos que pueda necesitar serializados. Este es un método mágico demjson
, pero probablemente sea algo en lo que quieras pensar, sin importar la implementación que elijas. La idea es que devuelva un objeto que sea directamente convertible a 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 (no ForeignKeys
, solo números y cadenas en la base de datos, etc.). De lo contrario, debe pensar seriamente en la forma correcta de implementar este método.
Tercero, llama demjson.JSON.encode(instance)
y tienes lo que quieres.
Si está preguntando cómo serializar un solo objeto de un modelo y sabe que solo obtendrá un objeto en el conjunto de consultas (por ejemplo, usando objects.get), 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?"}}
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 las frases sencillas:
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 de modelo a la que se puede acceder desde instancias y desde el modelo mismo.
Aquí está mi solución para esto, que le permite personalizar fácilmente el JSON y organizar registros relacionados
Primero implemente un método en el modelo. Llamo 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)
car.json()
Use la lista, 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")
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 = next(serializers.deserialize("json", serial)).object
.values()
es lo que necesitaba para convertir una instancia de modelo a JSON.
.values () documentación: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values
Ejemplo de uso con un modelo llamado Proyecto .
Nota: estoy usando Django Rest Framework
@csrf_exempt
@api_view(["GET"])
def get_project(request):
id = request.query_params['id']
data = Project.objects.filter(id=id).values()
if len(data) == 0:
return JsonResponse(status=404, data={'message': 'Project with id {} not found.'.format(id)})
return JsonResponse(data[0])
Resultado de una identificación válida:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
python
formato,from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
y python
formato?El json
formato devolverá el resultado como str
mientras python
que devolverá el resultado en list
oOrderedDict
OrderedDict
, nodict
No parece que pueda serializar una instancia, tendría 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 quedé sin el svn
lanzamiento de django, por lo que puede que no sea en versiones anteriores.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Devuelvo el dict de mi instancia
entonces devuelve algo como {'field1': value, "field2": value, ....}
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
Todas estas respuestas fueron un poco extravagantes en comparación con lo que esperaría de un marco, el método más simple, creo que con mucho, si está utilizando el resto del marco:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
Esto utiliza el serializador directamente, respetando los campos que ha definido en él, así como cualquier asociación, etc.
django.core
para hacer esto. ¿Alguna razón en particular para no usar serializar el conjunto de consultas?