Search code examples
pythondjangopostgresqldjango-rest-frameworkflat

change an imbricated list to a flat list in django, python


I want a flat list for my categories list in output, but this code doesn't do that. It still shows the categories in imbricated list. Can someone help me?

This is the code:

@api_view(['GET'])
def AllCategoriesList(request):
    categories = Categories.objects.filter(parent=None).prefetch_related(
        Prefetch('children', queryset=Categories.objects.all(), to_attr='subcategories')
    )
    
    def flatten_list(lst):
        flat_lst = []
        for item in lst:
            if isinstance(item, list):
                flat_lst.extend(flatten_list(item))
            else:
                flat_lst.append(item)
        
        return flat_lst
    
    category_list = []
    for category in categories:
        category_list.append(category)
        category_list.extend(category.children.all())

    flattened_list = flatten_list(category_list)

    serializer = CategorieSerializer(flattened_list, many=True)
    return Response(serializer.data)

I tried to change my code to use the flatten_list function, but it doesn't work.

This is the output:

 { "id": 1,
    "image_couverture": null,
    "children": [{ "id": 2,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "nouveau categorie",
        "descriptions": "categorie fille",
        "slug": "nouveau-categorie",
        "created_at": "2023-03-04T08:08:35.667959Z",
        "updated_at": null,
        "parent": 1
      }
    ],
    "nom_categorie": "Test categorie",
    "descriptions": "test categorie",
    "slug": "test-categorie",
    "created_at": "2023-03-04T06:43:42.628255Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 2,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "nouveau categorie",
    "descriptions": "categorie fille",
    "slug": "nouveau-categorie",
    "created_at": "2023-03-04T08:08:35.667959Z",
    "updated_at": null,
    "parent": 1
  },
  {
    "id": 3,
    "image_couverture": null,
    "children": [
      {
        "id": 4,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Boissons",
        "descriptions": "Test description",
        "slug": "boissons",
        "created_at": "2023-03-06T10:13:39.229660Z",
        "updated_at": null,
        "parent": 3
      }
    ],
    "nom_categorie": "Alimentation & vins",
    "descriptions": "Test Description",
    "slug": "alimentation-vins",
    "created_at": "2023-03-06T10:06:24.492310Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 4,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "Boissons",
    "descriptions": "Test description",
    "slug": "boissons",
    "created_at": "2023-03-06T10:13:39.229660Z",
    "updated_at": null,
    "parent": 3
  },
  {
    "id": 5,
    "image_couverture": null,
    "children": [
      {
        "id": 13,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "spa",
        "descriptions": "hotel bla",
        "slug": "spa",
        "created_at": "2023-03-07T16:54:15.145494Z",
        "updated_at": null,
        "parent": 5
      }
    ],
    "nom_categorie": "VOYAGES et LOCATIONS",
    "descriptions": "Test",
    "slug": "voyages-et-locations",
    "created_at": "2023-03-06T10:58:44.996614Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 13,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "spa",
    "descriptions": "hotel bla",
    "slug": "spa",
    "created_at": "2023-03-07T16:54:15.145494Z",
    "updated_at": null,
    "parent": 5
  },
  {
    "id": 6,
    "image_couverture": null,
    "children": [
      {
        "id": 12,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Ballon",
        "descriptions": "gfjfm jtukj gfdf",
        "slug": "ballon",
        "created_at": "2023-03-06T18:28:25.832572Z",
        "updated_at": null,
        "parent": 6
      }
    ],
    "nom_categorie": "SPORTS et FITNESS",
    "descriptions": "Test",
    "slug": "sports-et-fitness",
    "created_at": "2023-03-06T10:59:26.929241Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 12,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "Ballon",
    "descriptions": "gfjfm jtukj gfdf",
    "slug": "ballon",
    "created_at": "2023-03-06T18:28:25.832572Z",
    "updated_at": null,
    "parent": 6
  },
  {
    "id": 7,
    "image_couverture": null,
    "children": [
      {
        "id": 8,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Chaussures femme",
        "descriptions": "Test",
        "slug": "chaussures-femme",
        "created_at": "2023-03-06T11:15:08.421713Z",
        "updated_at": null,
        "parent": 7
      }
    ],
    "nom_categorie": "MODE FEMME",
    "descriptions": "Test",
    "slug": "mode-femme",
    "created_at": "2023-03-06T11:13:09.847437Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 8,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "Chaussures femme",
    "descriptions": "Test",
    "slug": "chaussures-femme",
    "created_at": "2023-03-06T11:15:08.421713Z",
    "updated_at": null,
    "parent": 7
  },
  {
    "id": 9,
    "image_couverture": null,
    "children": [
      {
        "id": 10,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "tafita-1",
        "descriptions": "hgjjgj",
        "slug": "tafita1",
        "created_at": "2023-03-06T18:15:23.355740Z",
        "updated_at": null,
        "parent": 9
      }
    ],
    "nom_categorie": "tafita",
    "descriptions": "nljbk",
    "slug": "tafita",
    "created_at": "2023-03-06T18:14:58.259709Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 10,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "tafita-1",
    "descriptions": "hgjjgj",
    "slug": "tafita1",
    "created_at": "2023-03-06T18:15:23.355740Z",
    "updated_at": null,
    "parent": 9
  },
  {
    "id": 11,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "Tech",
    "descriptions": "gd hgjkjg th",
    "slug": "tech",
    "created_at": "2023-03-06T18:25:00.949297Z",
    "updated_at": null,
    "parent": null
  },
  {
    "id": 14,
    "image_couverture": null,
    "children": [],
    "nom_categorie": "Hotel34",
    "descriptions": "DJGJ JGKJ",
    "slug": "hotel34",
    "created_at": "2023-03-07T16:57:03.666177Z",
    "updated_at": null,
    "parent": null
  }
]

Solution

  • If you seek to flatted/promote all nested dictionaries, you might look at something like this:

    Given input data as:

    data_raw = """
    [
      {
        "id": 1,
        "image_couverture": null,
        "children": [
          {
            "id": 2,
            "image_couverture": null,
            "children": [],
            "nom_categorie": "nouveau categorie",
            "descriptions": "categorie fille",
            "slug": "nouveau-categorie",
            "created_at": "2023-03-04T08:08:35.667959Z",
            "updated_at": null,
            "parent": 1
          }
        ],
        "nom_categorie": "Test categorie",
        "descriptions": "test categorie",
        "slug": "test-categorie",
        "created_at": "2023-03-04T06:43:42.628255Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 2,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "nouveau categorie",
        "descriptions": "categorie fille",
        "slug": "nouveau-categorie",
        "created_at": "2023-03-04T08:08:35.667959Z",
        "updated_at": null,
        "parent": 1
      },
      {
        "id": 3,
        "image_couverture": null,
        "children": [
          {
            "id": 4,
            "image_couverture": null,
            "children": [],
            "nom_categorie": "Boissons",
            "descriptions": "Test description",
            "slug": "boissons",
            "created_at": "2023-03-06T10:13:39.229660Z",
            "updated_at": null,
            "parent": 3
          }
        ],
        "nom_categorie": "Alimentation & vins",
        "descriptions": "Test Description",
        "slug": "alimentation-vins",
        "created_at": "2023-03-06T10:06:24.492310Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 4,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Boissons",
        "descriptions": "Test description",
        "slug": "boissons",
        "created_at": "2023-03-06T10:13:39.229660Z",
        "updated_at": null,
        "parent": 3
      },
      {
        "id": 5,
        "image_couverture": null,
        "children": [
          {
            "id": 13,
            "image_couverture": null,
            "children": [],
            "nom_categorie": "spa",
            "descriptions": "hotel bla",
            "slug": "spa",
            "created_at": "2023-03-07T16:54:15.145494Z",
            "updated_at": null,
            "parent": 5
          }
        ],
        "nom_categorie": "VOYAGES et LOCATIONS",
        "descriptions": "Test",
        "slug": "voyages-et-locations",
        "created_at": "2023-03-06T10:58:44.996614Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 13,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "spa",
        "descriptions": "hotel bla",
        "slug": "spa",
        "created_at": "2023-03-07T16:54:15.145494Z",
        "updated_at": null,
        "parent": 5
      },
      {
        "id": 6,
        "image_couverture": null,
        "children": [
          {
            "id": 12,
            "image_couverture": null,
            "children": [],
            "nom_categorie": "Ballon",
            "descriptions": "gfjfm jtukj gfdf",
            "slug": "ballon",
            "created_at": "2023-03-06T18:28:25.832572Z",
            "updated_at": null,
            "parent": 6
          }
        ],
        "nom_categorie": "SPORTS et FITNESS",
        "descriptions": "Test",
        "slug": "sports-et-fitness",
        "created_at": "2023-03-06T10:59:26.929241Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 12,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Ballon",
        "descriptions": "gfjfm jtukj gfdf",
        "slug": "ballon",
        "created_at": "2023-03-06T18:28:25.832572Z",
        "updated_at": null,
        "parent": 6
      },
      {
        "id": 7,
        "image_couverture": null,
        "children": [
          {
            "id": 8,
            "image_couverture": null,
            "children": [],
            "nom_categorie": "Chaussures femme",
            "descriptions": "Test",
            "slug": "chaussures-femme",
            "created_at": "2023-03-06T11:15:08.421713Z",
            "updated_at": null,
            "parent": 7
          }
        ],
        "nom_categorie": "MODE FEMME",
        "descriptions": "Test",
        "slug": "mode-femme",
        "created_at": "2023-03-06T11:13:09.847437Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 8,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Chaussures femme",
        "descriptions": "Test",
        "slug": "chaussures-femme",
        "created_at": "2023-03-06T11:15:08.421713Z",
        "updated_at": null,
        "parent": 7
      },
      {
        "id": 9,
        "image_couverture": null,
        "children": [
          {
            "id": 10,
            "image_couverture": null,
            "children": [],
            "nom_categorie": "tafita-1",
            "descriptions": "hgjjgj",
            "slug": "tafita1",
            "created_at": "2023-03-06T18:15:23.355740Z",
            "updated_at": null,
            "parent": 9
          }
        ],
        "nom_categorie": "tafita",
        "descriptions": "nljbk",
        "slug": "tafita",
        "created_at": "2023-03-06T18:14:58.259709Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 10,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "tafita-1",
        "descriptions": "hgjjgj",
        "slug": "tafita1",
        "created_at": "2023-03-06T18:15:23.355740Z",
        "updated_at": null,
        "parent": 9
      },
      {
        "id": 11,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Tech",
        "descriptions": "gd hgjkjg th",
        "slug": "tech",
        "created_at": "2023-03-06T18:25:00.949297Z",
        "updated_at": null,
        "parent": null
      },
      {
        "id": 14,
        "image_couverture": null,
        "children": [],
        "nom_categorie": "Hotel34",
        "descriptions": "DJGJ JGKJ",
        "slug": "hotel34",
        "created_at": "2023-03-07T16:57:03.666177Z",
        "updated_at": null,
        "parent": null
      }
    ]
    """
    

    Then you can:

    def flatten_list(data):
        flat_lst = []
    
        if isinstance(data, list):
            for item in data:
                flat_lst.append(item)
                flat_lst.extend(flatten_list(item))
            return flat_lst
    
        if isinstance(data, dict):
            ## ----------------------
            ## Use a copy of the items so we are not directly
            ## iterating over the dictionary
            ## ----------------------
            for key, value in list(data.items()):
                flat_lst.extend(flatten_list(value))
    
                ### ----------------------
                ### you don't want children": []
                ### ----------------------
                if isinstance(value, list):
                    del data[key]
                ### ----------------------
            ## ----------------------
        
        return flat_lst
    
    data = json.loads(data_raw)
    data = flatten_list(data)
    
    ## ---------------
    ## just the unique items (by id)
    ## ---------------
    data = list({item["id"]: item for item in data}.values())
    ## ---------------
    
    print(json.dumps(data, indent=4))
    

    That should give you:

    [
        {
            "id": 1,
            "image_couverture": null,
            "nom_categorie": "Test categorie",
            "descriptions": "test categorie",
            "slug": "test-categorie",
            "created_at": "2023-03-04T06:43:42.628255Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 2,
            "image_couverture": null,
            "nom_categorie": "nouveau categorie",
            "descriptions": "categorie fille",
            "slug": "nouveau-categorie",
            "created_at": "2023-03-04T08:08:35.667959Z",
            "updated_at": null,
            "parent": 1
        },
        {
            "id": 3,
            "image_couverture": null,
            "nom_categorie": "Alimentation & vins",
            "descriptions": "Test Description",
            "slug": "alimentation-vins",
            "created_at": "2023-03-06T10:06:24.492310Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 4,
            "image_couverture": null,
            "nom_categorie": "Boissons",
            "descriptions": "Test description",
            "slug": "boissons",
            "created_at": "2023-03-06T10:13:39.229660Z",
            "updated_at": null,
            "parent": 3
        },
        {
            "id": 5,
            "image_couverture": null,
            "nom_categorie": "VOYAGES et LOCATIONS",
            "descriptions": "Test",
            "slug": "voyages-et-locations",
            "created_at": "2023-03-06T10:58:44.996614Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 13,
            "image_couverture": null,
            "nom_categorie": "spa",
            "descriptions": "hotel bla",
            "slug": "spa",
            "created_at": "2023-03-07T16:54:15.145494Z",
            "updated_at": null,
            "parent": 5
        },
        {
            "id": 6,
            "image_couverture": null,
            "nom_categorie": "SPORTS et FITNESS",
            "descriptions": "Test",
            "slug": "sports-et-fitness",
            "created_at": "2023-03-06T10:59:26.929241Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 12,
            "image_couverture": null,
            "nom_categorie": "Ballon",
            "descriptions": "gfjfm jtukj gfdf",
            "slug": "ballon",
            "created_at": "2023-03-06T18:28:25.832572Z",
            "updated_at": null,
            "parent": 6
        },
        {
            "id": 7,
            "image_couverture": null,
            "nom_categorie": "MODE FEMME",
            "descriptions": "Test",
            "slug": "mode-femme",
            "created_at": "2023-03-06T11:13:09.847437Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 8,
            "image_couverture": null,
            "nom_categorie": "Chaussures femme",
            "descriptions": "Test",
            "slug": "chaussures-femme",
            "created_at": "2023-03-06T11:15:08.421713Z",
            "updated_at": null,
            "parent": 7
        },
        {
            "id": 9,
            "image_couverture": null,
            "nom_categorie": "tafita",
            "descriptions": "nljbk",
            "slug": "tafita",
            "created_at": "2023-03-06T18:14:58.259709Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 10,
            "image_couverture": null,
            "nom_categorie": "tafita-1",
            "descriptions": "hgjjgj",
            "slug": "tafita1",
            "created_at": "2023-03-06T18:15:23.355740Z",
            "updated_at": null,
            "parent": 9
        },
        {
            "id": 11,
            "image_couverture": null,
            "nom_categorie": "Tech",
            "descriptions": "gd hgjkjg th",
            "slug": "tech",
            "created_at": "2023-03-06T18:25:00.949297Z",
            "updated_at": null,
            "parent": null
        },
        {
            "id": 14,
            "image_couverture": null,
            "nom_categorie": "Hotel34",
            "descriptions": "DJGJ JGKJ",
            "slug": "hotel34",
            "created_at": "2023-03-07T16:57:03.666177Z",
            "updated_at": null,
            "parent": null
        }
    ]