Search code examples
djangodjango-rest-frameworkgroup-by

Django drf Serialize group by model field


Django drf Serialize group by model field I have drf endpoint i get this result, but i want to group this result by model field product_type, how i can implement this? i tryed like in this answer DRF: Serializer Group By Model Field but it didn't help me

[
    {
        "id": 1,
        "name": "Danwich ham and cheese",
        "product_type": "Snacks",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FF0059B799A17F57A9E64C725.avif",
        "grams": 210,
        "description": "Crispy ciabatta and the familiar combination of ham, chicken, mozzarella with fresh tomatoes, ranch sauce and garlic",
        "extra_info": "",
        "price": "3.28",
        "extra_ingredients": []
    },
    {
        "id": 2,
        "name": "Danwich Chorizo ​​BBQ",
        "product_type": "Snacks",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FF041FE1F94C903576DCFD01E.avif",
        "grams": 210,
        "description": "Rich taste of spicy chorizo ​​sausages and spicy pepperoni with burger and barbecue sauces, fresh tomatoes, pickled cucumbers, mozzarella and onions in a golden ciabatta",
        "extra_info": "",
        "price": "3.28",
        "extra_ingredients": []
    },
    {
        "id": 3,
        "name": "Chocolate milkshake",
        "product_type": "Cocktails",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FA24D1E919FA050D8BA21F8E9.avif",
        "grams": null,
        "description": "Charming chocolate delicacy. Try a milkshake with cocoa and ice cream",
        "extra_info": "0.3 L",
        "price": "2.71",
        "extra_ingredients": []
    },
    {
        "id": 4,
        "name": "Strawberry milkshake",
        "product_type": "Cocktails",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FB231A5BF82B0A99A1B12339C.avif",
        "grams": null,
        "description": "No matter what time of year it is, this cocktail with strawberry concentrate will take you back to summer in one sip.",
        "extra_info": "0.3 L",
        "price": "2.71",
        "extra_ingredients": []
    },
    {
        "id": 5,
        "name": "Coffee Americano",
        "product_type": "Cofe",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61B044583596548A59078BBD33.avif",
        "grams": null,
        "description": "A couple of sips of hot Americano and you'll be ready to conquer the day.",
        "extra_info": "0.4 L",
        "price": "1.28",
        "extra_ingredients": []
    },
    {
        "id": 6,
        "name": "Coffee Cappuccino",
        "product_type": "Cofe",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61AE1813B4AB42D8927D061035.avif",
        "grams": null,
        "description": "The king among coffee drinks is the classic cappuccino. For lovers of balanced coffee and milk taste",
        "extra_info": "0.4 L",
        "price": "1.87",
        "extra_ingredients": []
    },
    {
        "id": 7,
        "name": "Orange juice Rich",
        "product_type": "Beverages",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61B223E75EB71498BCAA0D4A0D.avif",
        "grams": null,
        "description": "",
        "extra_info": "1 L",
        "price": "3.05",
        "extra_ingredients": []
    },
    {
        "id": 8,
        "name": "Apple juice Rich",
        "product_type": "Beverages",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61B27F1652B9A918BDDD753D8D.avif",
        "grams": null,
        "description": "",
        "extra_info": "1 L",
        "price": "3.05",
        "extra_ingredients": []
    },
    {
        "id": 9,
        "name": "Cheesecake New York",
        "product_type": "Desserts",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EEE20B6B6EC471AB74AB8F8885775B.avif",
        "grams": null,
        "description": "We tried a thousand desserts and finally found the guests' favorite - the most delicate curd cheesecake",
        "extra_info": "1 psc. 100 grams",
        "price": "2.11",
        "extra_ingredients": []
    },
    {
        "id": 10,
        "name": "Banana cheesecake with chocolate cookies",
        "product_type": "Desserts",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE797014D8F94683D580455892ABA1.avif",
        "grams": 100,
        "description": "Sunny on the outside and bright in taste on the inside. Summer novelty - delicate cheesecake with banana and chocolate cookies",
        "extra_info": "",
        "price": "1.87",
        "extra_ingredients": []
    },
    {
        "id": 11,
        "name": "BBQ",
        "product_type": "Sauces",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EEE205E4AFB158AFCB34392A1F6FC1.avif",
        "grams": 25,
        "description": "Branded sauce with a smoky aroma for pizza sides and hot appetizers, 25 g",
        "extra_info": "1 psc",
        "price": "0.53",
        "extra_ingredients": []
    },
    {
        "id": 12,
        "name": "Garlic Sause",
        "product_type": "Sauces",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE79700EBD09E7A7603B26879BC7B0.avif",
        "grams": 25,
        "description": "Branded sauce with garlic flavor for pizza sides and hot appetizers, 25 g",
        "extra_info": "1 psc",
        "price": "0.53",
        "extra_ingredients": []
    }
]

how i can group by product_type in something like this

{
    "Snacks": [
      {
        "id": 1,
        "name": "Danwich ham and cheese",
        "product_type": "Snacks",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FF0059B799A17F57A9E64C725.avif",
        "grams": 210,
        "description": "Crispy ciabatta and the familiar combination of ham, chicken, mozzarella with fresh tomatoes, ranch sauce and garlic",
        "extra_info": "",
        "price": "3.28",
        "extra_ingredients": []
    },
    {
        "id": 2,
        "name": "Danwich Chorizo ​​BBQ",
        "product_type": "Snacks",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FF041FE1F94C903576DCFD01E.avif",
        "grams": 210,
        "description": "Rich taste of spicy chorizo ​​sausages and spicy pepperoni with burger and barbecue sauces, fresh tomatoes, pickled cucumbers, mozzarella and onions in a golden ciabatta",
        "extra_info": "",
        "price": "3.28",
        "extra_ingredients": []
    }
    ],
    "Cocktails": [
      {
        "id": 3,
        "name": "Chocolate milkshake",
        "product_type": "Cocktails",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FA24D1E919FA050D8BA21F8E9.avif",
        "grams": null,
        "description": "Charming chocolate delicacy. Try a milkshake with cocoa and ice cream",
        "extra_info": "0.3 L",
        "price": "2.71",
        "extra_ingredients": []
    },
    {
        "id": 4,
        "name": "Strawberry milkshake",
        "product_type": "Cocktails",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE796FB231A5BF82B0A99A1B12339C.avif",
        "grams": null,
        "description": "No matter what time of year it is, this cocktail with strawberry concentrate will take you back to summer in one sip.",
        "extra_info": "0.3 L",
        "price": "2.71",
        "extra_ingredients": []
    }
    ],
    "Cofe": [
      {
        "id": 5,
        "name": "Coffee Americano",
        "product_type": "Cofe",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61B044583596548A59078BBD33.avif",
        "grams": null,
        "description": "A couple of sips of hot Americano and you'll be ready to conquer the day.",
        "extra_info": "0.4 L",
        "price": "1.28",
        "extra_ingredients": []
    },
    {
        "id": 6,
        "name": "Coffee Cappuccino",
        "product_type": "Cofe",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61AE1813B4AB42D8927D061035.avif",
        "grams": null,
        "description": "The king among coffee drinks is the classic cappuccino. For lovers of balanced coffee and milk taste",
        "extra_info": "0.4 L",
        "price": "1.87",
        "extra_ingredients": []
    }
    ],
    "Beverages": [
      {
        "id": 7,
        "name": "Orange juice Rich",
        "product_type": "Beverages",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61B223E75EB71498BCAA0D4A0D.avif",
        "grams": null,
        "description": "",
        "extra_info": "1 L",
        "price": "3.05",
        "extra_ingredients": []
    },
    {
        "id": 8,
        "name": "Apple juice Rich",
        "product_type": "Beverages",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE7D61B27F1652B9A918BDDD753D8D.avif",
        "grams": null,
        "description": "",
        "extra_info": "1 L",
        "price": "3.05",
        "extra_ingredients": []
    }
    ],
    "Deserts": [
      {
        "id": 9,
        "name": "Cheesecake New York",
        "product_type": "Desserts",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EEE20B6B6EC471AB74AB8F8885775B.avif",
        "grams": null,
        "description": "We tried a thousand desserts and finally found the guests' favorite - the most delicate curd cheesecake",
        "extra_info": "1 psc. 100 grams",
        "price": "2.11",
        "extra_ingredients": []
    },
    {
        "id": 10,
        "name": "Banana cheesecake with chocolate cookies",
        "product_type": "Desserts",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE797014D8F94683D580455892ABA1.avif",
        "grams": 100,
        "description": "Sunny on the outside and bright in taste on the inside. Summer novelty - delicate cheesecake with banana and chocolate cookies",
        "extra_info": "",
        "price": "1.87",
        "extra_ingredients": []
    }
    ],
    "Sauces": [
      {
        "id": 11,
        "name": "BBQ",
        "product_type": "Sauces",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EEE205E4AFB158AFCB34392A1F6FC1.avif",
        "grams": 25,
        "description": "Branded sauce with a smoky aroma for pizza sides and hot appetizers, 25 g",
        "extra_info": "1 psc",
        "price": "0.53",
        "extra_ingredients": []
    },
    {
        "id": 12,
        "name": "Garlic Sause",
        "product_type": "Sauces",
        "img_url": "https://media.dodostatic.net/image/r:292x292/11EE79700EBD09E7A7603B26879BC7B0.avif",
        "grams": 25,
        "description": "Branded sauce with garlic flavor for pizza sides and hot appetizers, 25 g",
        "extra_info": "1 psc",
        "price": "0.53",
        "extra_ingredients": []
    }
    ]
}

my code

.models.py

class Product(models.Model):

    PRODUCT_TYPE_CHOICES = [
        ('Snacks', 'Snacks'),
        ('Beverages', 'Beverages'),
        ('Cocktails', 'Cocktails'),
        ('Cofe', 'Cofe'),
        ('Desserts', 'Desserts'),
        ('Sauces', 'Sauces'),
    ]


    name = models.CharField(max_length=50)
    product_type = models.CharField(max_length=50, choices=PRODUCT_TYPE_CHOICES)
    img_url = models.URLField()
    grams = models.PositiveSmallIntegerField(blank=True, null=True)
    description = models.TextField(max_length=500, blank=True)
    extra_ingredients = models.ManyToManyField(Extra_Ingredients, blank=True)
    extra_info = models.CharField(max_length=50, blank=True)
    price = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self) -> str:
        return f'{self.product_type}'

.serialers.py

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'


.view.py

class ProductGroupApiView(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

Solution

  • I understood your intention to classify and return the data through the product_type key value.

    Added a process for classifying returned values in ProductGroupApiView. Returns the value classified as product_type.

    views.py

    from rest_framework import generics, status
    from rest_framework.response import Response
    from .models import Product
    from .serializers import ProductSerializer
    
    # Create your views here.
    
    class ProductGroupApiView(generics.ListAPIView):
        queryset = Product.objects.all()
        serializer_class = ProductSerializer
        
        def get(self, request, *args, **kwargs):
          response = super().get(request, *args, **kwargs)
          group = {product["product_type"]: [] for product in response.data}
          {group[product["product_type"]].append(product) for product in response.data}
    
          return Response(group, status=status.HTTP_200_OK)    
    

    But I also recommend this solution.(Can you also tell me why this solution wasn't successful?) DRF: Serializer Group By Model Field

    enter image description here