将 Django 查询集输出为 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15874233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Output Django queryset as JSON
提问by user2232982
I want to serialize my queryset, and I want it in a format as this view outputs:
我想序列化我的查询集,并且我希望它采用此视图输出的格式:
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')
I simply don't know how to output the queryset instead of the manual data in the example.
我只是不知道如何输出查询集而不是示例中的手动数据。
I've tried
我试过了
json.dumps({"data": self.get_queryset()})
and
和
serializers.serialize("json", {'data': self.get_queryset()})
but it wont work. What am I doing wrong? Do I need to make a custom JSON Encoder?
但它不会工作。我究竟做错了什么?我需要制作自定义 JSON 编码器吗?
回答by Mark Mishyn
You can use JsonResponsewith values. Simple example:
您可以将JsonResponse与values一起使用。简单的例子:
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})
Or another approach with Django's built-in serializers:
或者使用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')
In this case result is slightly different (without indent by default):
在这种情况下,结果略有不同(默认情况下没有缩进):
[
{
"model": "some_app.some_model",
"pk": 1,
"fields": {
"name": "Elon",
"age": 48,
...
}
},
...
]
I have to say, it is good practice to use something like marshmallowto serialize queryset.
我不得不说,使用棉花糖之类的东西来序列化查询集是一种很好的做法。
...and a few notes for better performance:
...以及一些提高性能的注意事项:
- use pagination if your queryset is big;
- use
objects.values()to specify list of required fields to avoid serialization and sending to client unnecessary model's fields (you also can passfieldstoserializers.serialize);
- 如果您的查询集很大,请使用分页;
- 用于
objects.values()指定必填字段列表以避免序列化并向客户端发送不必要的模型字段(您也可以传递fields给serializers.serialize);
回答by freakish
It didn't work, because QuerySets are not JSON serializable.
它不起作用,因为 QuerySets 不是 JSON 可序列化的。
1) In case of json.dumpsyou have to explicitely convert your QuerySet to JSON serializable objects:
1) 如果json.dumps您必须明确地将您的 QuerySet 转换为 JSON 可序列化对象:
class Model(model.Model):
def as_dict(self):
return {
"id": self.id,
# other stuff
}
And the serialization:
和序列化:
dictionaries = [ obj.as_dict() for obj in self.get_queryset() ]
return HttpResponse(json.dumps({"data": dictionaries}), content_type='application/json')
2) In case of serializers. Serializers accept either JSON serializable object or QuerySet, but a dictionary containing a QuerySet is neither. Try this:
2) 在序列化程序的情况下。序列化器接受 JSON 可序列化对象或 QuerySet,但包含 QuerySet 的字典两者都不是。尝试这个:
serializers.serialize("json", self.get_queryset())
Read more about it here:
在此处阅读更多相关信息:
回答by serfer2
For a efficient solution, you can use .values()function to get a list of dict objects and then dump it to json response by using i.e. JsonResponse(remember to set safe=False).
对于有效的解决方案,您可以使用.values()函数来获取 dict 对象列表,然后使用 ie JsonResponse将其转储到 json 响应(记住设置safe=False)。
Once you have your desired queryset object, transform it to JSON response like this:
获得所需的查询集对象后,将其转换为 JSON 响应,如下所示:
...
data = list(queryset.values())
return JsonResponse(data, safe=False)
You can specify field names in .values()function in order to return only wanted fields (the example above will return all model fields in json objects).
您可以在.values()函数中指定字段名称以仅返回想要的字段(上面的示例将返回 json 对象中的所有模型字段)。
回答by Marcus Lind
If the goal is to build an API that allow you to access your models in JSON format I recommend you to use the django-restframeworkthat is an enormously popular package within the Django community to achieve this type of tasks.
如果目标是构建一个允许您以 JSON 格式访问模型的 API,我建议您使用django-restframeworkDjango 社区中非常流行的包来完成此类任务。
It include useful features such as Pagination, Defining Serializers, Nested models/relations and more. Even if you only want to do minor Javascript tasks and Ajax calls I would still suggest you to build a proper API using the Django Rest Framework instead of manually defining the JSON response.
它包括有用的功能,例如分页、定义序列化程序、嵌套模型/关系等。即使您只想执行次要的 Javascript 任务和 Ajax 调用,我仍然建议您使用 Django Rest Framework 构建适当的 API,而不是手动定义 JSON 响应。
回答by k15
Try this:
尝试这个:
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

