Il y a beaucoup de documentation sur la façon de sérialiser un modèle QuerySet, mais comment sérialiser simplement en JSON les champs d'une instance de modèle?
Il y a beaucoup de documentation sur la façon de sérialiser un modèle QuerySet, mais comment sérialiser simplement en JSON les champs d'une instance de modèle?
Réponses:
Vous pouvez facilement utiliser une liste pour envelopper l'objet requis et c'est tout ce dont les sérialiseurs django ont besoin pour le sérialiser correctement, par exemple:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
[0]
à la fin de votre dernière ligne, comme @DavorLucic l'a suggéré? Et pas besoin de virgule de fin dans votre liste littérale (pour l'amour de PEP8;).
Si vous avez affaire à une liste d'instances de modèle, le mieux que vous puissiez faire est d'utiliser serializers.serialize()
, cela répondra parfaitement à vos besoins.
Cependant, vous devez faire face à un problème en essayant de sérialiser un seul objet, pas un list
objet. De cette façon, afin de se débarrasser des différents hacks, il suffit d'utiliser Django model_to_dict
(si je ne me trompe pas, serializers.serialize()
cela dépend aussi):
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Vous avez maintenant juste besoin d'un json.dumps
appel direct pour le sérialiser vers json:
import json
serialized = json.dumps(dict_obj)
C'est tout! :)
datetime
champs. Résolu de cette façon json.loads(serialize('json', [obj]))[0]
pendant que le sérialiseur estdjango.core.serializers.serialize
Pour éviter le wrapper de tableau, supprimez-le avant de renvoyer la réponse:
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')
J'ai aussi trouvé cet article intéressant sur le sujet:
http://timsaylor.com/convert-django-model-instances-to-dictionaries
Il utilise django.forms.models.model_to_dict, qui ressemble à l'outil parfait pour le travail.
Il y a une bonne réponse à cela et je suis surpris qu'elle n'ait pas été mentionnée. En quelques lignes, vous pouvez gérer les dates, les modèles et tout le reste.
Créez un encodeur personnalisé capable de gérer les modèles:
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)
Maintenant, utilisez-le lorsque vous utilisez json.dumps
json.dumps(data, cls=ExtendedEncoder)
Désormais, les modèles, les dates et tout peuvent être sérialisés et il n'est pas nécessaire que ce soit dans un tableau ou sérialisé et non sérialisé. Tout ce que vous avez personnalisé peut simplement être ajouté à la default
méthode.
Vous pouvez même utiliser le JsonResponse natif de Django de cette façon:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
et json.dump
. De cette façon, vous n'avez pas besoin de modifier le flux de travail de l'application car vous utilisez des objets personnalisés ou ajoutez un autre appel de méthode avant la conversion en json. Ajoutez simplement votre code de conversion dans l'encodeur et vous êtes prêt à partir.
Il semble que ce que vous demandez implique de sérialiser la structure de données d'une instance de modèle Django pour l'interopérabilité. Les autres affiches sont correctes: si vous vouliez que le formulaire sérialisé soit utilisé avec une application python qui peut interroger la base de données via l'API de Django, alors vous voudriez sérialiser un jeu de requêtes avec un objet. Si, d'un autre côté, vous avez besoin d'un moyen de regonfler l'instance de modèle ailleurs sans toucher à la base de données ou sans utiliser Django, alors vous avez un peu de travail à faire.
Voici ce que je fais:
Tout d'abord, j'utilise demjson
pour la conversion. C'est ce que j'ai trouvé en premier, mais ce n'est peut-être pas le meilleur. Ma mise en œuvre dépend de l'une de ses fonctionnalités, mais il devrait y avoir des moyens similaires avec d'autres convertisseurs.
Deuxièmement, implémentez une json_equivalent
méthode sur tous les modèles dont vous pourriez avoir besoin en série. C'est une méthode magique pour demjson
, mais c'est probablement quelque chose à quoi vous voudrez réfléchir, quelle que soit l'implémentation que vous choisissez. L'idée est de renvoyer un objet directement convertible en json
(c'est- à -dire un tableau ou un dictionnaire). Si vous voulez vraiment faire cela automatiquement:
def json_equivalent(self):
dictionary = {}
for field in self._meta.get_all_field_names()
dictionary[field] = self.__getattribute__(field)
return dictionary
Cela ne vous sera utile que si vous avez une structure de données complètement plate (non ForeignKeys
, uniquement des nombres et des chaînes dans la base de données, etc.). Sinon, vous devriez sérieusement réfléchir à la bonne façon de mettre en œuvre cette méthode.
Troisièmement, appelez demjson.JSON.encode(instance)
et vous avez ce que vous voulez.
Si vous demandez comment sérialiser un seul objet à partir d'un modèle et que vous savez que vous n'obtiendrez qu'un seul objet dans le jeu de requêtes (par exemple, en utilisant objects.get), utilisez quelque chose comme:
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")
ce qui vous donnerait quelque chose de la forme:
{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What's up?"}}
J'ai résolu ce problème en ajoutant une méthode de sérialisation à mon modèle:
def toJSON(self):
import simplejson
return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))
Voici l'équivalent détaillé de ceux qui sont opposés aux 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
est une liste ordonnée de champs de modèle accessibles depuis les instances et depuis le modèle lui-même.
Voici ma solution pour cela, qui vous permet de personnaliser facilement le JSON ainsi que d'organiser les enregistrements associés
Tout d'abord, implémentez une méthode sur le modèle. J'appelle json
mais vous pouvez l'appeler comme vous voulez, par exemple:
class Car(Model):
...
def json(self):
return {
'manufacturer': self.manufacturer.name,
'model': self.model,
'colors': [color.json for color in self.colors.all()],
}
Ensuite, dans la vue que je fais:
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()
Utilisez la liste, cela résoudra le problème
Étape 1:
result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();
Étape 2:
result=list(result) #after getting data from model convert result to list
Étape 3:
return HttpResponse(json.dumps(result), content_type = "application/json")
Pour sérialiser et désérialiser, utilisez ce qui suit:
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()
est ce dont j'avais besoin pour convertir une instance de modèle en JSON.
Documentation .values (): https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values
Exemple d'utilisation avec un modèle appelé Project .
Remarque: j'utilise 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])
Résultat d'un identifiant valide:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
Si vous souhaitez renvoyer l' objet de modèle unique en tant que réponse json à un client, vous pouvez effectuer cette solution simple:
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
et python
format?Le json
format renverra le résultat comme str
alors que python
retournera le résultat dans l'un list
ou l' autreOrderedDict
OrderedDict
, pasdict
Il ne semble pas que vous puissiez sérialiser une instance, vous devrez sérialiser un QuerySet d'un objet.
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
Je suis à court de la svn
version de django, donc cela peut ne pas être dans les versions antérieures.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Je renvoie le dict de mon instance
donc il renvoie quelque chose comme {'champ1': valeur, "champ2": valeur, ....}
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
Toutes ces réponses étaient un peu hacky par rapport à ce que j'attendrais d'un framework, la méthode la plus simple, je pense de loin, si vous utilisez le framework rest:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
Cela utilise directement le sérialiseur, en respectant les champs que vous avez définis dessus, ainsi que les associations, etc.
django.core
pour ce faire. Une raison particulière de ne pas utiliser la sérialisation du jeu de requêtes?