uff123
uff123

Reputation: 3

Django: Display Count of Ratings in ListView

I just started learing django and I'm trying to display a Product with the Amount of Ratings it has in a ListView. But I fail to generate the expected output.

models.py

class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField(max_length=255, default=None)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    
    
class ProductRating(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='product_rating')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    stars = models.SmallIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])

views.py

class ProductListView(LoginRequiredMixin, ListView):
    model = Product

    def get_queryset(self):
        return Product.objects.annotate(avg_rating=Avg('product_rating__stars')).order_by('-avg_rating')

    def get_context_data(self, **kwargs):
        data = super(ProductListView, self).get_context_data(**kwargs)
        data['product_rating_count'] = Product.objects.annotate(Count('product_rating'))
        return data

template

{{ product.name }} {{ product.avg_rating }} {{ product_rating_count }}

This displays the name and average-rating as expected but puts a Queryset containing all Products next to each single product like this:

<QuerySet [<Product: testp1>, <Product: testp2>, <Product: testp3>, <Product: testp4>]>

Upvotes: 0

Views: 342

Answers (1)

Arjun Shahi
Arjun Shahi

Reputation: 7330

In your template you can do this.

{% for product in products %}

{{ product.name }} {{ product.avg_rating }} 

Rating count: {{ product.product_rating.all.count }}

{% endfor %}

Upvotes: 1

Related Questions