django 带有文件和对象嵌套数组的DRF表单数据不采用对象嵌套数组

to94eoyn  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(99)

使用formdata时无法发送嵌套对象。由于我有大量的文件使用base64不是一个解决方案。目前的解决方案是使用JSON.stringify从客户端product_timings和发送它作为一个单一的领域,但我想知道如果正常模态字段与文件上传是可能的DRF.这是我的APIView

class ProductCreateApi(APIView):
    permission_classes = [permissions.DjangoModelPermissions]
    queryset = Product.objects.all().order_by("-created_at")
    parser_class = [MultiPartParser, FormParser, JSONParser, FileUploadParser]
    
    class ProductCreateSerializer(serializers.ModelSerializer):
        class ProductCreateProductTimingSerializer(serializers.ModelSerializer):
            class Meta:
                model = ProductTiming
                fields = ['start_time', 'end_time']
        product_timings = ProductCreateProductTimingSerializer(write_only=True, many=True)
        product_images = serializers.ListField(
            child=serializers.ImageField(allow_empty_file=False, use_url=False),
            write_only=True
        )

        class Meta:
            model = Product
            fields = '__all__'

在岗位上,我累了
product_timings[0][start_time]: 09:30:00
product_timings[0][start_time]: 09:30:00
它仍然会抛出验证错误消息,如

{
    "product_timings": [
        {
            "start_time": [
                "This field is required."
            ],
            "end_time": [
                "This field is required."
            ]
        }
    ]
}

请注意,product_images的base64图像字段和product_timings的单个JSON字段都不是我正在寻找的解决方案。

1rhkuytd

1rhkuytd1#

您正在寻找的格式没有点,也没有辅助[]
products[0]starttime
这里有一个在python3.6或更高版本中完成此操作的辅助函数,但它很容易适应。

def flatten_dict_for_formdata(input_dict: dict):
    """
    Recursively flattens nested dict() for passing as form data
    > {"a": [{"b": "c"}]         => "a[0]b":    "c"
    > "i": {"j": "k"}}           => "i.j":      "k"
    > "x": {"y": {"z": [1, 2]}}  => "x.y.z[0]": 1, "x.y.z[1]": 2,
    """

    results = {}

    def flatten(value, prefix="", previous=None):
        if isinstance(value, dict):
            if previous == "dict":
                prefix += "."

            for key, value in value.items():
                flatten(value, prefix + key, previous="dict")

        elif isinstance(value, (list, tuple, set)):
            for i, value in enumerate(value):
                flatten(value, prefix + f"[{i}]")

        else:
            results[prefix] = value

    flatten(input_dict, "")
    return results

输出的更长示例:

flatten_dict_for_formdata(
    {
        "character": {
            "name": {"first": "Clark"},
            "favorite_color": ("Red", "White")
        },
        "superpower": "Super Strength",
        "appearances": [
            {
                "title": "Action Comics #1",
                "dialog": [
                    {
                        "speaker": "Clark",
                        "tokens": ["Up", "In", "The", "Sky"]
                    }
                ]
            }
        ]
    },
)

转换为:

"character.name.first": "Clark",
"character.favorite_color[0]": "Red",
"character.favorite_color[1]": "White",
"superpower": "Super Strength",
"appearances[0]title": "Action Comics #1",
"appearances[0]dialog[0]speaker": "Clark",
"appearances[0]dialog[0]tokens[0]": "Up",
"appearances[0]dialog[0]tokens[1]": "In",
"appearances[0]dialog[0]tokens[2]": "The",
"appearances[0]dialog[0]tokens[3]": "Sky"

相关问题