0

This is my models.py:

class Category(models.Model):
    category_des = models.CharField(max_length=250)

class Type(models.Model):
    type_des = models.CharField(max_length=250)

class Product(models.Model):
    category_id = models.ForeignKey(Category, on_delete=models.CASCADE)
    type_id = models.ForeignKey(Type, on_delete=models.CASCADE)
    product_name = models.CharField(max_length=250)
    product_price = models.FloatField()

What I want to do is to divide products into menus list and extras list and group them by category like this:

Category 1:

extra 1.a

extra 1.b

menu 1.c

menu 1.d

Category 2:

extra 2.e

extra 2.f

menu 2.g

menu 2.h

and this is what I did in views.py:

class MenuList(generics.ListCreateAPIView):
    queryset = models.Product.objects.filter(type_id=1).annotate("category_id")
    serializer_class = serializers.ProductSerializer
    
class MenuDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = models.Product.objects.filter(type_id=1).annotate("category_id")
    serializer_class = serializers.ProductSerializer

class ExtraList(generics.ListCreateAPIView):
    queryset = models.Product.objects.filter(type_id=2).annotate("category_id")
    serializer_class = serializers.ProductSerializer
class ExtraDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = models.Product.objects.filter(type_id=2).annotate("category_id")
    serializer_class = serializers.ProductSerializer

I got this error: TypeError: QuerySet.annotate() received non-expression(s): category_id.

amine4392
  • 79
  • 6
  • I don't understand why you want to use annotate, your Product model has a foreign key to category, so the category id will already be included. – Guillaume May 07 '21 at 19:16
  • @Guillaume I just want to group my products (menus and extras) by the category id – amine4392 May 07 '21 at 19:47
  • Are you sure that you don't mean that you want to order by category id? Group by would be useful only if you plan to (for example) sum on a particular field. – Guillaume May 07 '21 at 20:02
  • To explain the message: You are annotating a fixed string (and also you rely on Django to give the annotation a name). The error message tells you that plain strings are not the type of thing that can be used as an annotation. You would need to use `Value("my string")` to change that. – Lutz Prechelt Aug 03 '21 at 09:59

1 Answers1

2

Query Expressions and F() Objects

Django 3.2 Documentation

class MenuList(generics.ListCreateAPIView):
    queryset = models.Product.objects.filter(type_id=1).annotate(F("category_id"))
    serializer_class = serializers.ProductSerializer

Try and make use of an F() object to add on the category_id to each object in your queryset.

Harben
  • 1,802
  • 1
  • 11
  • 16