Django2.0通用视图中JsonResponse始终返回字符串问题
解决Django 2.0 ListView返回JSON字符串而非JSON对象的问题
看起来你遇到的问题是因为Django原生的serializers.serialize()返回的是JSON格式的字符串,而你直接把这个字符串传给JsonResponse时,它会把这个字符串当成普通文本再序列化一次,导致最终返回的是被引号包裹、内部引号转义的字符串,而不是前端需要的JSON对象数组。
下面给你几种可行的解决办法,从原生Django实现到更优雅的长期方案都有:
方法一:原生Django手动构造数据(无需额外依赖)
你可以遍历查询集,手动把每个模型实例转成Python字典,再传给JsonResponse,这样它会正确序列化为JSON对象数组:
from django.views.generic import ListView from django.http import JsonResponse from .models import Question class QuestionListView(ListView): model = Question def get(self, request, *args, **kwargs): # 获取查询集 queryset = self.get_queryset() # 手动构造字典列表 data = [] for question in queryset: data.append({ "pk": question.pk, "created": question.created.isoformat(), "modified": question.modified.isoformat(), "question": question.question, "category": question.category, "event": question.event, "answer": question.answer }) # 传入列表时需要设置safe=False(默认只允许字典) return JsonResponse(data, safe=False)
方法二:用json.loads解析序列化后的字符串
如果你还是想用serializers.serialize(),可以先把它返回的JSON字符串解析成Python对象(列表+字典),再传给JsonResponse:
import json from django.views.generic import ListView from django.http import JsonResponse from django.core import serializers from .models import Question class QuestionListView(ListView): model = Question def get(self, request, *args, **kwargs): queryset = self.get_queryset() # 序列化得到JSON字符串 serialized_str = serializers.serialize("json", queryset) # 解析成Python对象 data = json.loads(serialized_str) # 同样需要safe=False因为是列表 return JsonResponse(data, safe=False)
方法三:用Django REST Framework(更优雅的长期方案)
如果你的项目后续会有更多前后端协作的需求,推荐用Django REST Framework(DRF)来处理序列化,它的通用视图会自动帮你处理好JSON响应:
- 先安装DRF:
pip install djangorestframework
- 在
settings.py的INSTALLED_APPS里添加:
INSTALLED_APPS = [ # ... 其他应用 'rest_framework', ]
- 新建
serializers.py,写一个模型序列化器:
from rest_framework import serializers from .models import Question class QuestionSerializer(serializers.ModelSerializer): class Meta: model = Question # 指定要返回的字段,和你需要的一致 fields = ["pk", "created", "modified", "question", "category", "event", "answer"]
- 改写视图为DRF的
ListAPIView:
from rest_framework.generics import ListAPIView from .models import Question from .serializers import QuestionSerializer class QuestionListView(ListAPIView): queryset = Question.objects.all() serializer_class = QuestionSerializer
这样访问这个视图时,直接返回的就是标准的JSON数组,前端可以直接解析使用,不需要额外处理。
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

