将Django queryset输出为JSON

2024-04-29 13:29:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我想序列化我的queryset,我希望它的格式与此视图输出的格式相同:

class JSONListView(ListView):
    queryset = Users.objects.all()

    def get(self, request, *args, **kwargs):
        return HttpResponse(json.dumps({'data': [['bar','foo','bar','foo'],['foo','bar','foo','bar']]}, indent=4), content_type='application/json')

我只是不知道如何输出示例中的queryset而不是手动数据。

我试过了

json.dumps({"data": self.get_queryset()})

以及

serializers.serialize("json", {'data': self.get_queryset()})

但这行不通。我做错什么了?我需要定制JSON编码器吗?


Tags: self视图jsondataget序列化foo格式
3条回答

它不起作用,因为queryset不是JSON可序列化的。

1)在json.dumps情况下,必须明确地将QuerySet转换为JSON可序列化对象:

class Model(model.Model):
    def as_dict(self):
        return {
            "id": self.id,
            # other stuff
        }

以及序列化:

dictionaries = [ obj.as_dict() for obj in self.get_queryset() ]
return HttpResponse(json.dumps({"data": dictionaries}), content_type='application/json')

2)如果是序列化程序。序列化程序接受JSON可序列化对象或QuerySet,但包含QuerySet的字典两者都不接受。试试这个:

serializers.serialize("json", self.get_queryset())

请在此处阅读更多信息:

https://docs.djangoproject.com/en/dev/topics/serialization/

可以将JsonResponsevalues一起使用。简单示例:

from django.http import JsonResponse

def some_view(request):
    data = list(SomeModel.objects.values())  # use list(), because QuerySet is not JSON serializable
    return JsonResponse(data, safe=False)  # or JsonResponse({'data': data})

或者使用Django's built-in serializers的另一种方法:

from django.core import serializers
from django.http import HttpResponse

def some_view(request):
    qs = SomeModel.objects.all()
    qs_json = serializers.serialize('json', qs)
    return HttpResponse(qs_json, content_type='application/json')

在这种情况下,结果略有不同(默认情况下没有缩进):

[
    {
        "model": "some_app.some_model",
        "pk": 1,
        "fields": {
            "name": "Ivan",
            "age": 35,
            ...
        }
    },
    ...
]

我不得不说,使用marshmallow之类的东西序列化queryset是一个很好的实践。

…以及一些提高性能的注意事项:

  • 如果查询集很大,请使用分页
  • 使用objects.values()指定所需字段的列表,以避免序列化并发送给客户端不必要的模型字段(您还可以将fields传递给serializers.serialize

为了获得有效的解决方案,可以使用.values()函数获取dict对象的列表,然后使用JsonResponse(请记住设置safe=False)将其转储到json响应。

一旦获得了所需的queryset对象,就将其转换为JSON响应,如下所示:

...
data = list(queryset.values())
return JsonResponse(data, safe=False)

您可以在.values()函数中指定字段名,以便只返回所需的字段(上面的示例将返回json对象中的所有模型字段)。

相关问题 更多 >