88

我想序列化我的查询集,并且我希望它采用此视图输出的格式:

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

我根本不知道如何输出查询集而不是示例中的手动数据。

我试过了

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

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

但它不会工作。我究竟做错了什么?我需要制作自定义 JSON 编码器吗?

4

8 回答 8

143

您可以将JsonResponsevalues一起使用。简单的例子:

from django.http import JsonResponse

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

或者使用Django 的内置序列化程序的另一种方法:

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": "Elon",
            "age": 48,
            ...
        }
    },
    ...
]

我不得不说,使用棉花糖之类的东西来序列化查询集是一种很好的做法。

...以及一些注意事项以获得更好的性能:

  • 如果您的查询集很大,请使用分页;
  • 用于objects.values()指定必填字段列表以避免序列化并发送给客户端不必要的模型字段(您也可以传递fieldsserializers.serialize);
于 2016-06-15T15:07:34.157 回答
43

它不起作用,因为 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/

于 2013-04-08T08:27:15.307 回答
20

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

获得所需的查询集对象后,将其转换为 JSON 响应,如下所示:

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

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

于 2018-12-31T11:31:36.840 回答
8

要返回您检索到的查询集,queryset = Users.objects.all(),首先需要对它们进行序列化。

序列化是将一种数据结构转换为另一种数据结构的过程。使用基于类的视图,您可以像这样返回 JSON。

from django.core.serializers import serialize
from django.http import JsonResponse
from django.views.generic import View

class JSONListView(View):
    def get(self, request, *args, **kwargs):
        qs = User.objects.all()
        data = serialize("json", qs)
        return JsonResponse(data)

这将输出一个 JSON 列表。有关其工作原理的更多详细信息,请查看我的博客文章如何使用 Django 返回 JSON 响应。它更详细地介绍了您将如何进行此操作。

于 2020-10-16T19:24:04.337 回答
5

如果目标是构建一个允许您以 JSON 格式访问模型的 API,我建议您使用django-restframeworkDjango 社区中非常流行的包来完成此类任务。

它包括有用的功能,例如分页、定义序列化程序、嵌套模型/关系等等。即使您只想执行次要的 Javascript 任务和 Ajax 调用,我仍然建议您使用 Django Rest Framework 构建适当的 API,而不是手动定义 JSON 响应。

于 2017-11-16T03:32:30.317 回答
0

将查询集转换为 JSON 的另一种方法是将必要的元素附加到带有循环的空列表中。它提供设计可定制的 JSON。

queryset = Users.objects.all()
output = []
for query in queryset:
   output.append('id': query.id, 'name': query.name, etc...)
return JSONResponse(output, safe=False) 
于 2021-10-22T08:57:37.263 回答
-2

尝试这个:

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


    def get(self, request, *args, **kwargs):
        data = {}
        data["users"] = get_json_list(queryset)
        return JSONResponse(data)


def get_json_list(query_set):
    list_objects = []
    for obj in query_set:
        dict_obj = {}
        for field in obj._meta.get_fields():
            try:
                if field.many_to_many:
                    dict_obj[field.name] = get_json_list(getattr(obj, field.name).all())
                    continue
                dict_obj[field.name] = getattr(obj, field.name)
            except AttributeError:
                continue
        list_objects.append(dict_obj)
    return list_objects
于 2016-08-18T21:07:53.500 回答
-3
from django.http import JsonResponse

def SomeFunction():
       dict1 = {}

       obj = list( Mymodel.objects.values() )

       dict1['data']=obj

return JsonResponse(dict1)

试试这个 Django 代码

于 2020-12-03T04:27:52.590 回答