web-dev-qa-db-ja.com

Django / pythonでモデルオブジェクトのリストを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)

Json.dumps()のカスタムシリアライザー(エンコーダー)を作成しました。

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)

1つのオブジェクトのみをシリアル化すると、それを行うことができます。オブジェクトのリストをシリアル化しようとすると、

[ objects..] is not JSON serializable

私は検索しましたが、どこで作業すべきかわかりませんでした。モデルオブジェクトのリスト用にカスタムシリアライザーを作成することを考えていました。

17
gc5

カスタムエンコーダーは再帰的に呼び出されません。実際には、カスタムエンコーダーを使用してnotを使用し、代わりに、シリアル化する前にオブジェクトを単純なpythonタイプに変換することをお勧めします。

モデルにas_jsonまたは同様の名前のメソッドを追加し、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)

次に、あなたの意見で:

# 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")
39
Martijn Pieters

Djangoモデルをシリアル化するために見つけた最良の方法は、Django.core.serializersモデルリストをJSON、XML、またはYAMLにシリアル化します。カスタムシリアル化コードは必要ありません!ドキュメントはこちら: https://docs.djangoproject.com/en/dev/topics/serialization/

これが私の実装です。

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')

最終結果:

[{"pk": 1, "model": "lead.lead", "fields": {"Twitter_handle": "johndoe", "name": "John Doe", "phone": "1(234)567-8910", "email": "[email protected]", "github_handle": "johndoe"}}]
18
matthewfisher

最も簡単なソリューション:

def index(request):
    data = serializers.serialize('json', Product.objects.all())
    return HttpResponse(data, content_type='application/json')
1
Cody