You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework实现无固定键字典结构Payload的Serializer

问题原因

你之前在外层序列化器中定义了固定字段test,相当于要求Payload顶层结构必须包含test键,和你实际顶层直接以UUID为键的字典结构不匹配,所以需要去掉固定字段定义,直接对整个顶层字典做校验。

实现方案

首先确认你定义的内部操作序列化器是正确的,你之前的代码里有笔误:DictField的child参数引用了不存在的RelationshipAuthorizeObjectSerializer,替换为你定义的UserOperationSerializer即可。
你可以根据需求选择以下两种实现方式:

方式1:直接在视图层校验(无需额外定义外层序列化器)

适合仅在单个视图使用的场景:

import uuid
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response

# 内部操作对象序列化器保持不变
class UserOperationSerializer(serializers.Serializer):
    operation = serializers.ChoiceField(choices=["Create", "Delete"])
    operationId = serializers.UUIDField()
    user = serializers.CharField()
    immediate = serializers.BooleanField()

class YourOperationView(APIView):
    def post(self, request):
        # 定义顶层字典校验规则:值为UserOperation结构
        top_level_serializer = serializers.DictField(
            child=UserOperationSerializer()
        )
        # 校验输入
        validated_data = top_level_serializer.run_validation(request.data)
        # 可选:额外校验所有键为合法UUID
        for key in validated_data.keys():
            try:
                uuid.UUID(key)
            except ValueError:
                raise serializers.ValidationError(f"键{key}不是合法UUID格式")
        
        # 后续业务逻辑
        return Response(validated_data)

方式2:封装为可复用的独立序列化器

适合多处复用的场景,自定义顶层序列化器的校验逻辑:

import uuid
from rest_framework import serializers

class UserOperationSerializer(serializers.Serializer):
    operation = serializers.ChoiceField(choices=["Create", "Delete"])
    operationId = serializers.UUIDField()
    user = serializers.CharField()
    immediate = serializers.BooleanField()

class UserOperationsSerializer(serializers.Serializer):
    # 不需要定义任何固定字段,重写校验逻辑直接处理整个输入字典
    def to_internal_value(self, data):
        op_serializer = UserOperationSerializer()
        validated_result = {}
        for key, op_data in data.items():
            # 校验键为合法UUID
            try:
                uuid.UUID(key)
            except ValueError:
                raise serializers.ValidationError({key: "不是合法的UUID格式"})
            # 校验值的结构
            validated_op = op_serializer.run_validation(op_data)
            validated_result[key] = validated_op
        return validated_result

使用方式和普通序列化器完全一致:

serializer = UserOperationsSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
# 校验通过后的数据可以直接通过validated_data获取
validated_data = serializer.validated_data

注:DRF原生BooleanField默认支持解析字符串格式的"true"/"false",你Payload中传入的字符串类型布尔值不需要额外做转换处理。

内容的提问来源于stack exchange,提问作者user2880391

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 08:54:03