Il y a beaucoup de documentation sur la façon de sérialiser un modèle QuerySet, mais comment sérialiser en JSON les champs d'une instance de modèle?
Vous pouvez facilement utiliser une liste pour encapsuler l'objet requis. C'est tout ce dont Django les sérialiseurs 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, ])
Si vous traitez avec une liste d'instances de modèles, 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 objet nique, pas un list
d'objets. De cette façon, pour vous débarrasser de différents hacks, utilisez simplement le model_to_dict
De Django (si je ne me trompe pas, serializers.serialize()
s'appuie également dessus):
from Django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Vous avez maintenant besoin d’un appel direct json.dumps
Pour le sérialiser en json:
import json
serialized = json.dumps(dict_obj)
C'est ça! :)
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 trouvé cet article intéressant sur le sujet aussi:
http://timsaylor.com/convert-Django-model-instances-todictionaries
Il utilise Django.forms.models.model_to_dict, qui semble être l'outil idéal pour ce travail.
Il semble que ce que vous demandez concerne la sérialisation de la structure de données d’une instance de modèle Django aux fins d’interopérabilité. Les autres affiches sont correctes: si vous souhaitiez utiliser le formulaire sérialisé avec une application python pouvant interroger la base de données via l’API de Django, vous voudriez alors sérialiser un queryset avec un seul objet. Si, par contre, vous avez besoin d’un moyen de regonfler l’instance de modèle ailleurs sans toucher à la base de données ni utiliser Django, vous avez un peu de travail à faire.
Voici ce que je fais:
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. Mon implémentation dépend de l'une de ses fonctionnalités, mais il devrait exister des méthodes similaires avec d'autres convertisseurs.
Deuxièmement, implémentez une méthode json_equivalent
Sur tous les modèles que vous pourriez avoir besoin de sérialiser. C’est une méthode magique pour demjson
, mais c’est probablement une chose à laquelle vous allez vouloir penser quelle que soit l’implémentation que vous choisissez. L'idée est que vous retourniez un objet directement convertible en json
(c'est-à-dire un tableau ou un dictionnaire). Si vous voulez vraiment le faire 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 (pas de 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 vous n'obtiendrez qu'un seul objet dans le jeu de requête (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")
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?"}}
Il y a une bonne réponse à cela et je suis surpris que cela n'ait pas été mentionné. Avec quelques lignes, vous pouvez gérer les dates, les modèles et tout le reste.
Créez un encodeur personnalisé pouvant 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)
Maintenant, 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és et non sérialisés.
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 verbal pour 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 auxquels on peut accéder à partir d'instances et du modèle lui-même.
Voici ma solution pour cela, qui vous permet de personnaliser facilement le JSON et d'organiser les enregistrements associés.
Tout d'abord implémenter une méthode sur le modèle. J'appelle est json
mais vous pouvez l'appeler comme bon vous semble, 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()],
}
Alors dans la vue 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)
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 les éléments suivants:
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
python
format,from Django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
et python
le format?Le format json
renverra le résultat sous la forme str
alors que python
retournera le résultat est soit list
ou OrderedDict
Si vous souhaitez renvoyer le objet unique en tant que réponse json à un client, vous pouvez utiliser 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))
Il ne semble pas que vous puissiez sérialiser une instance, vous devez 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 n’utilise plus la version svn
de Django, il est donc possible que ce ne soit pas dans les versions précédentes.
que diriez-vous de cette façon:
def ins2dic(obj):
SubDic = obj.__dict__
del SubDic['id']
del SubDic['_state']
return SubDic
ou exclure tout ce que vous ne voulez pas.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Je retourne le dict de mon instance
donc, il retourne quelque chose comme {'field1': value, "field2": value, ....}