[Answered ]-DRF formdata with file and nested array of objects not taking nested array of objects

1👍

The format your are looking for has no dots, and no secondary []:

products[0]starttime

Here is a helper function to do this in python3.6 or greater, but it is easy to adapt.

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

A longer example of the output:

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"]
                    }
                ]
            }
        ]
    },
)

Converts to:

"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"
👤Andrew

Leave a comment