23

我正在尝试序列化定义为的模型对象列表:

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)

当我只序列化一个对象时,我可以做到。当我尝试序列化对象列表时,我得到

[ objects..] is not JSON serializable

我搜索了但我没有找到在哪里工作。我正在考虑为模型对象列表编写一个自定义序列化程序。

4

3 回答 3

46

自定义编码器不会被递归调用。实际上最好不要使用自定义编码器,而是在序列化之前将对象转换为简单的 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")
于 2012-10-23T13:11:29.873 回答
22

我发现序列化 Django 模型的最佳方法是django.core.serializers将模型列表序列化为 JSON、XML 或 YAML。无需自定义序列化代码!文档在这里:https ://docs.djangoproject.com/en/dev/topics/serialization/

这是我的实现:

铅/模型.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)

铅/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='application/json')

最终结果:

[{"pk": 1, "model": "lead.lead", "fields": {"twitter_handle": "johndoe", "name": "John Doe", "phone": "1(234)567-8910", "email": "john@doe.com", "github_handle": "johndoe"}}]
于 2013-05-17T19:19:11.313 回答
2

最简单的解决方案:

def index(request):
    data = serializers.serialize('json', Product.objects.all())
    return HttpResponse(data, content_type='application/json')
于 2017-11-01T11:08:44.137 回答