我想序列化我的查询集,并且我希望它采用此视图输出的格式:
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 编码器吗?
您可以将 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})
或者使用 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,
...
}
},
...
]
我不得不说,使用像 marshmallow 这样的东西来序列化查询集是很好的做法。
...以及一些以获得更好性能的注意事项:
objects.values()
指定必填字段列表,以避免序列化并向客户端发送不必要的模型字段(您也可以将 fields
传递给 serializers.serialize
);它不起作用,因为 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())
在这里阅读更多相关信息:
为了获得有效的解决方案,您可以使用 .values() 函数获取 dict 对象列表,然后使用 JsonResponse 将其转储到 json 响应(请记住设置
safe=False
)。
一旦获得所需的查询集对象,请将其转换为 JSON 响应,如下所示:
...
data = list(queryset.values())
return JsonResponse(data, safe=False)
您可以在
.values()
函数中指定字段名称,以便仅返回所需的字段(上面的示例将返回 json 对象中的所有模型字段)。
要返回使用
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 响应。它更详细地介绍了您将如何解决这个问题。
如果目标是构建一个允许您以 JSON 格式访问模型的 API,我建议您使用
django-restframework
,这是 Django 社区中非常流行的包来实现此类任务。
它包括有用的功能,例如分页、定义序列化器、嵌套模型/关系等等。即使您只想执行较小的 Javascript 任务和 Ajax 调用,我仍然建议您使用 Django Rest Framework 构建适当的 API,而不是手动定义 JSON 响应。
将查询集转换为 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)
扩展序列化器。序列化器是真正可行的方法,但是出于某种原因,如果您真的不想这样做,那么以下应该为您提供查询集中的一些 json。
from django.core import serializers
from rest_framework.response import Response
peoples = People.objects.all()
data = serializers.serialize('json', peoples)
json_data = json.loads(data)
return Response(json_data)
根据一些回复,我最终创建了一个模板过滤器:
# your-app/templatetags/your-file.py
from django.core import serializers
@register.filter
def json(data):
return serializers.serialize('json', data)
模板过滤器接受查询集。你可以通过
YourModel.objects.all()
{# your-app/templates/your-app/your-template.html #}
<script>
let data = {{ rows|json|safe }}
</script>
试试这个:
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
from django.http import JsonResponse
def SomeFunction():
dict1 = {}
obj = list( Mymodel.objects.values() )
dict1['data']=obj
return JsonResponse(dict1)
在 Django 中尝试此代码