1

In my Product model I have a function total_thumbs_up which count how many users gave thumb up for this product.

class Product(models.Model):
    class ProductObjects(models.Manager):
        def get_queryset(self):
            return super().get_queryset().filter(status='published')
    objects = models.Manager()

    thumbs_up = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name="product_thumbs", blank=True)

    def total_thumbs_up(self):
        return self.thumbs_up.count()

In my views file I have two classes like this. I need to GET sorted products by amount of thumbs_up but this line ('-thumbs_up', '0'), doesn't work fine. I need to have something like ('-total_thumbs_up', '0'),. How can I set it there?

class ProductFilter(django_filters.FilterSet):
    order_by_field = 'ordering'
    ordering = OrderingFilter(
        fields=(
            ('-thumbs_up', '0'),
            ('price', '1'),
            ('-price', '2'),
            ('id', '3'),
            ('-published', '4'),
        )
    )


class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]
    pagination_class = Pagination
    filter_backends = [DjangoFilterBackend,
                       filters.OrderingFilter, filters.SearchFilter]
    parser_classes = [MultipartJsonParser, parsers.JSONParser]
    search_fields = ['name']

    filter_class = ProductFilter
    ...

1 Answer 1

1

Something like:

from django.db.models import Count

ordered_products = Product.objects.all().annotate(
    thumbs_count = Count('thumbs_up')
).order_by('-thumbs_count')

Note, the annotated name thumbs_count must be different than the model the method name total_thumbs_up.

EDIT:

In your ModelViewSet you can do:

class ProductViewSet(...):

    ...
    queryset = Product.objects.all().select_related(
        'thumbs_up'
    ).annotate(
        thumbs_count = Count('thumbs_up')
    ).order_by(
        '-thumbs_count'
    )
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.