Es gibt eine Menge Dokumentation zum Serialisieren eines Model QuerySet, aber wie serialisieren Sie einfach die Felder einer Model Instance in JSON?
Es gibt eine Menge Dokumentation zum Serialisieren eines Model QuerySet, aber wie serialisieren Sie einfach die Felder einer Model Instance in JSON?
Antworten:
Sie können das erforderliche Objekt einfach mit einer Liste umschließen, und das ist alles, was Django-Serialisierer benötigen, um es korrekt zu serialisieren, z.
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
[0]
am Ende deiner letzten Zeile, wie @DavorLucic vorgeschlagen hat? Und in Ihrem Listenliteral muss kein Komma nachgestellt werden (aus Liebe zu PEP8;).
Wenn Sie mit einer Liste von Modellinstanzen arbeiten, die Sie am besten verwenden können serializers.serialize()
, passt sie perfekt zu Ihren Anforderungen.
Sie haben jedoch ein Problem mit dem Versuch, ein einzelnes Objekt und kein Objekt zu serialisieren list
. Um verschiedene Hacks loszuwerden, verwenden Sie einfach Djangos model_to_dict
(wenn ich mich nicht irre, verlassen serializers.serialize()
Sie sich auch darauf):
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Sie brauchen jetzt nur noch einen direkten json.dumps
Aufruf, um es an json zu serialisieren:
import json
serialized = json.dumps(dict_obj)
Das ist es! :) :)
datetime
Feldern fehl . Auf diese Weise gelöst, json.loads(serialize('json', [obj]))[0]
während Serializer istdjango.core.serializers.serialize
Um den Array-Wrapper zu vermeiden, entfernen Sie ihn, bevor Sie die Antwort zurückgeben:
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')
Ich fand diesen interessanten Beitrag auch zu diesem Thema:
http://timsaylor.com/convert-django-model-instances-to-dictionaries
Es verwendet django.forms.models.model_to_dict, das wie das perfekte Werkzeug für den Job aussieht.
Es gibt eine gute Antwort darauf und ich bin überrascht, dass es nicht erwähnt wurde. Mit ein paar Zeilen können Sie Daten, Modelle und alles andere verarbeiten.
Erstellen Sie einen benutzerdefinierten Encoder, der Modelle verarbeiten kann:
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)
Verwenden Sie es jetzt, wenn Sie json.dumps verwenden
json.dumps(data, cls=ExtendedEncoder)
Jetzt können Modelle, Daten und alles serialisiert werden und es muss nicht mehr in einem Array oder serialisiert und unserialisiert sein. Alles, was Sie haben, das benutzerdefiniert ist, kann einfach zur default
Methode hinzugefügt werden.
Sie können Djangos native JsonResponse sogar folgendermaßen verwenden:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
und json.dump
Methoden. Auf diese Weise müssen Sie den Workflow der Anwendung nicht ändern, da Sie benutzerdefinierte Objekte verwenden oder einen anderen Methodenaufruf hinzufügen, bevor Sie in json konvertieren. Fügen Sie einfach Ihren Konvertierungscode in den Encoder ein und Sie können loslegen.
Es hört sich so an, als würden Sie die Datenstruktur einer Django-Modellinstanz für die Interoperabilität serialisieren. Die anderen Poster sind korrekt: Wenn Sie möchten, dass das serialisierte Formular mit einer Python-Anwendung verwendet wird, die die Datenbank über Djangos API abfragen kann, möchten Sie ein Abfrageset mit einem Objekt serialisieren. Wenn Sie andererseits eine Möglichkeit benötigen, die Modellinstanz an einer anderen Stelle wieder aufzublasen, ohne die Datenbank zu berühren oder Django zu verwenden, müssen Sie ein wenig arbeiten.
Folgendes mache ich:
Zunächst verwende ich demjson
für die Konvertierung. Es war zufällig das, was ich zuerst gefunden habe, aber es ist vielleicht nicht das Beste. Meine Implementierung hängt von einer ihrer Funktionen ab, aber es sollte ähnliche Möglichkeiten mit anderen Konvertern geben.
Zweitens implementieren Sie eine json_equivalent
Methode für alle Modelle, die möglicherweise serialisiert werden müssen. Dies ist eine magische Methode demjson
, aber wahrscheinlich möchten Sie darüber nachdenken, egal für welche Implementierung Sie sich entscheiden. Die Idee ist, dass Sie ein Objekt zurückgeben, in das direkt konvertiert werden kann json
(dh ein Array oder ein Wörterbuch). Wenn Sie dies wirklich automatisch tun möchten:
def json_equivalent(self):
dictionary = {}
for field in self._meta.get_all_field_names()
dictionary[field] = self.__getattribute__(field)
return dictionary
Dies ist für Sie nur hilfreich, wenn Sie eine vollständig flache Datenstruktur haben (nein ForeignKeys
, nur Zahlen und Zeichenfolgen in der Datenbank usw.). Andernfalls sollten Sie ernsthaft darüber nachdenken, wie Sie diese Methode richtig implementieren können.
Drittens rufen demjson.JSON.encode(instance)
Sie an und Sie haben, was Sie wollen.
Wenn Sie fragen, wie ein einzelnes Objekt aus einem Modell serialisiert werden soll und Sie wissen, dass Sie nur ein Objekt im Abfrageset erhalten (z. B. mithilfe von objects.get), verwenden Sie Folgendes:
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")
das würde dir etwas von der Form bringen:
{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What's up?"}}
Ich habe dieses Problem gelöst, indem ich meinem Modell eine Serialisierungsmethode hinzugefügt habe:
def toJSON(self):
import simplejson
return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))
Hier ist das ausführliche Äquivalent für diejenigen, die Einzeiler ablehnen:
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
ist eine geordnete Liste von Modellfeldern, auf die von Instanzen und vom Modell selbst aus zugegriffen werden kann.
Hier ist meine Lösung dafür, mit der Sie den JSON einfach anpassen und zugehörige Datensätze organisieren können
Implementieren Sie zunächst eine Methode für das Modell. Ich rufe an, json
aber du kannst es nennen, wie du willst, zB:
class Car(Model):
...
def json(self):
return {
'manufacturer': self.manufacturer.name,
'model': self.model,
'colors': [color.json for color in self.colors.all()],
}
Dann mache ich in der Ansicht:
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()
Verwenden Sie Liste, es wird das Problem lösen
Schritt 1:
result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();
Schritt 2:
result=list(result) #after getting data from model convert result to list
Schritt 3:
return HttpResponse(json.dumps(result), content_type = "application/json")
Verwenden Sie zum Serialisieren und Deserialisieren Folgendes:
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()
ist das, was ich brauchte, um eine Modellinstanz in JSON zu konvertieren.
Dokumentation zu .values (): https://docs.djangoproject.com/de/3.0/ref/models/querysets/#values
Beispiel für die Verwendung mit einem Modell namens Project .
Hinweis: Ich verwende das 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])
Ergebnis einer gültigen ID:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
Wenn Sie das einzelne Modellobjekt als JSON-Antwort an einen Client zurückgeben möchten , können Sie diese einfache Lösung ausführen:
from django.forms.models import model_to_dict
from django.http import JsonResponse
movie = Movie.objects.get(pk=1)
return JsonResponse(model_to_dict(movie))
python
Format,from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
und python
Format?Das json
Format gibt das Ergebnis zurück, str
während python
das Ergebnis entweder list
oder zurückgegeben wirdOrderedDict
OrderedDict
nichtdict
Es scheint nicht, dass Sie eine Instanz serialisieren können, sondern Sie müssen ein QuerySet eines Objekts serialisieren.
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
Ich habe svn
keine Django-Version mehr, daher ist dies möglicherweise nicht in früheren Versionen der Fall.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Ich gebe das Diktat meiner Instanz zurück
es gibt also so etwas wie {'field1': value, "field2": value, ....} zurück
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
Alle diese Antworten waren ein wenig hackig im Vergleich zu dem, was ich von einem Framework erwarten würde, der einfachsten Methode, denke ich bei weitem, wenn Sie das restliche Framework verwenden:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
Hierbei wird der Serializer direkt verwendet, wobei die darin definierten Felder sowie etwaige Zuordnungen usw. berücksichtigt werden.
django.core
, um dies zu tun. Gibt es einen bestimmten Grund, das Abfrageset nicht zu serialisieren?