Python3.7+Django:如何返回仅含模型属性的传统JSON格式?
问题:如何让Django视图返回不含model/pk/fields的扁平JSON?
我正在使用Python 3.7和Django,现有一个处理Ajax请求的视图get_hints,用于返回标题含相似词汇的文章。代码如下:
# Ajax request that returns articles with similar words in the titles def get_hints(request): ... s = ArticlesService() objects = s.get_hints(article) data = serializers.serialize('json', objects) return HttpResponse(data, content_type="application/json")
其中get_hints方法返回模型对象数组,但前端收到的JSON格式包含model、pk、fields嵌套,例如:
[{ "model": "mydb.article", "pk": 60945, "fields": { "title": "Cooking Eggplant", "path": "https://thecookingblog.com/abcde", "label": "" } }, ...]
请问能否返回不含model、fields的传统JSON,直接呈现对象属性,如:
{ "title": "Cooking Eggplant", "path": "https://thecookingblog.com/abcde", "label": "" }
解决方案
当然可以!Django自带的serializers.serialize()方法默认会生成包含模型元信息的嵌套结构,但我们有好几种方式可以生成你想要的扁平JSON格式,下面给你详细说几个实用方案:
方法一:手动构造字典列表(无额外依赖)
这是最直接的方式,不需要引入其他库,只需要遍历查询到的模型对象,把需要的字段手动提取出来构造成字典列表,再转成JSON即可:
import json from django.http import HttpResponse def get_hints(request): # ... 你的其他业务逻辑(比如获取article参数等) s = ArticlesService() objects = s.get_hints(article) # 手动构建扁平结构的字典列表 flat_data = [] for obj in objects: flat_data.append({ 'title': obj.title, 'path': obj.path, 'label': obj.label # 这里可以添加任何你需要返回的模型字段 }) # 将列表转为JSON字符串并返回 return HttpResponse(json.dumps(flat_data), content_type="application/json")
这种方式简单直观,适合字段不多的场景。
方法二:使用Django REST Framework(DRF)的ModelSerializer(推荐复杂场景)
如果你的项目已经在使用Django REST Framework,或者以后有更复杂的序列化需求(比如字段验证、嵌套关系处理等),用DRF的序列化器会更优雅:
首先定义一个针对Article模型的序列化器:
from rest_framework import serializers from .models import Article # 替换成你的Article模型路径 class ArticleHintSerializer(serializers.ModelSerializer): class Meta: model = Article fields = ['title', 'path', 'label'] # 指定需要返回的字段
然后修改你的视图函数,用DRF的Response来返回数据:
from rest_framework.response import Response from rest_framework.decorators import api_view from .serializers import ArticleHintSerializer # 导入上面定义的序列化器 @api_view(['GET']) # 根据你的实际请求方法调整(比如POST) def get_hints(request): # ... 你的其他业务逻辑 s = ArticlesService() objects = s.get_hints(article) # 使用序列化器处理多个对象(many=True) serializer = ArticleHintSerializer(objects, many=True) # DRF的Response会自动处理JSON格式,无需手动转换 return Response(serializer.data)
DRF的序列化器不仅能生成扁平JSON,还支持自定义字段、数据校验等功能,扩展性很强。
方法三:自定义可复用的序列化函数
如果需要在多个视图里用到这种扁平序列化逻辑,可以封装一个通用函数,避免重复代码:
import json from django.http import HttpResponse def serialize_flat_objects(objects, field_list): """ 将模型对象列表序列化为扁平结构的JSON :param objects: 模型对象列表 :param field_list: 需要包含的字段名列表 :return: JSON字符串 """ flat_data = [] for obj in objects: item = {} for field in field_list: item[field] = getattr(obj, field) flat_data.append(item) return json.dumps(flat_data) # 在视图中使用这个函数 def get_hints(request): # ... 你的其他业务逻辑 s = ArticlesService() objects = s.get_hints(article) data = serialize_flat_objects(objects, ['title', 'path', 'label']) return HttpResponse(data, content_type="application/json")
这个函数可以在任何需要的地方调用,只需要传入对象列表和要提取的字段名即可。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

