Comment sérialiser en JSON une liste d'objets modèles en django / python

j'essaie de sérialiser une liste d'objet model défini comme:

class AnalysisInput(models.Model):
    input_user = models.CharField(max_length=45)
    input_title = models.CharField(max_length=45)
    input_date = models.DateTimeField()
    input_link = models.CharField(max_length=100)

j'ai écrit un serializer personnalisé (encoder) pour json.décharges():

class AnalysisInputEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, AnalysisInput):
            return { "input_id" : obj.id,
                    "input_user" : obj.input_user,
                    "input_title" : obj.input_title,
                    "input_date" : obj.input_date.isoformat(),
                    "input_link" : obj.input_link }
        return json.JSONEncoder.default(self, obj)

Quand Je ne sérialise qu'un seul objet, je suis capable de le faire. Lorsque j'essaie de sérialiser une liste d'objet que j'obtiens

[ objects..] is not JSON serializable

j'ai cherché mais je n'ai pas trouvé où travailler.. Je pensais écrire un serializer personnalisé aussi pour la liste d'objet modèle.

17
demandé sur Martijn Pieters 2012-10-23 17:03:53

3 réponses

un encodeur personnalisé n'est pas appelé récursivement. Vous sont effectivement mieux en utilisant un encodeur personnalisé, et à la place Convertissez vos objets en types python simples avant de sérialiser.

Vous pouvez ajouter un as_json ou méthode nommée de la même façon à votre modèle et appelant que chaque fois que vous avez besoin d'un résultat JSON:

class AnalysisInput(models.Model):
    input_user = models.CharField(max_length=45)
    input_title = models.CharField(max_length=45)
    input_date = models.DateTimeField()
    input_link = models.CharField(max_length=100)

    def as_json(self):
        return dict(
            input_id=self.id, input_user=self.input_user,
            input_title=self.input_title, 
            input_date=self.input_date.isoformat(),
            input_link=self.input_link)

Alors à votre avis:

# one result
return HttpResponse(json.dumps(result.as_json()), content_type="application/json")

# a list of results
results = [ob.as_json() for ob in resultset]
return HttpResponse(json.dumps(results), content_type="application/json")
34
répondu Martijn Pieters 2015-11-17 08:12:31

le meilleur moyen que j'ai trouvé pour sérialiser vos modèles Django est d'utiliser django.core.serializers pour sérialiser votre liste de modèles en JSON, XML, ou YAML. Aucun code de sérialisation personnalisé n'est requis! La Documentation est ici:https://docs.djangoproject.com/en/dev/topics/serialization/

Voici mon oeuvre:

lead/models.py:

from django.db import models

class Lead(models.Model):
    name = models.CharField(max_length=50)
    email = models.CharField(max_length=256)
    phone = models.CharField(max_length=20)
    twitter_handle = models.CharField(max_length=20)
    github_handle = models.CharField(max_length=20)

lead/views.py:

from django.http import HttpResponse
from django.core import serializers
from lead.models import Lead

def index(request):
    leads_as_json = serializers.serialize('json', Lead.objects.all())
    return HttpResponse(leads_as_json, content_type='json')

Le résultat:

[{"pk": 1, "model": "lead.lead", "fields": {"twitter_handle": "johndoe", "name": "John Doe", "phone": "1(234)567-8910", "email": "john@doe.com", "github_handle": "johndoe"}}]
18
répondu matthewfisher 2013-05-17 19:19:11

solution la plus simple:

def index(request):
    data = serializers.serialize('json', Product.objects.all())
    return HttpResponse(data, content_type='application/json')
1
répondu Cody 2017-11-01 11:08:44