DRF中如何在views内提取模型JSONField的字段用于序列化
解决方案
错误原因说明
你调用json.dump()得到字符串是因为这个方法的作用是将Python字典/列表序列化为JSON格式字符串,属于方向搞反了。另外Django ORM读取JSONField字段时已经自动完成了JSON反序列化,你拿到的included字段本身就是可直接操作的Python列表,不需要手动调用任何json转换方法。
具体实现步骤
1. 配置路由匹配动态type
首先在urls.py中配置动态路径参数,用来接收people/animal这类类型值:
# urls.py from django.urls import path from .views import ResourceView urlpatterns = [ path('<str:resource_type>/', ResourceView.as_view(), name='resource-api'), ]
2. 编写序列化器
根据你需要的返回结构编写序列化器,支持动态attributes字段输出:
# serializers.py from rest_framework import serializers # 动态attributes序列化器,不需要预定义字段 class DynamicAttributesSerializer(serializers.Serializer): def to_representation(self, instance): return instance class IncludedResourceSerializer(serializers.Serializer): id = serializers.CharField() type = serializers.CharField() attributes = DynamicAttributesSerializer()
3. 视图逻辑编写
在视图中过滤对应type的资源并返回:
# views.py from rest_framework.views import APIView from rest_framework.response import Response from .models import YourResourceModel # 替换为你自己的模型类 from .serializers import IncludedResourceSerializer class ResourceView(APIView): def get(self, request, *args, **kwargs): # 从路径获取动态资源类型 resource_type = kwargs["resource_type"] # 查询对应的模型实例,此处根据你的业务逻辑调整查询条件 resource_obj = YourResourceModel.objects.first() # 直接操作included字段(已经是Python列表,无需转换) matched_resources = [ item for item in resource_obj.included if item.get("type") == resource_type ] # 只需要返回attributes内容时使用下方返回逻辑 # attributes_list = [item["attributes"] for item in matched_resources] # return Response(attributes_list) # 符合参考JSON:API结构的返回逻辑 return Response({ "data": resource_obj.data, "included": IncludedResourceSerializer(matched_resources, many=True).data })
可选优化
如果你的业务长期需要遵循JSON:API规范开发,可以直接使用djangorestframework-jsonapi扩展库,内置了对included、relationships等规范字段的原生支持,不需要手动写过滤逻辑。
内容的提问来源于stack exchange,提问作者Flower
相关产品推荐
相关产品推荐

