I am trying to show display the average rating for a given single product from every ratings made by users on this single product.
Which I managed to do. However my code seems to render all products and relating reviews and not just the specific product.
Clearly, I am telling the code, somewhere, to render all products instead of one. But I am not too sure where. I think it's coming form the code in my views.py.
Something to specify also, in the same page, I am trying to display:
- Average review per product (that's what I am working on)
- All reviews from different user on the specific product (that works)
Is it 2. that creates a problem? Should I also make a reference to the product_id in the second line of the views too? (if so, where?)
Models
class Product(models.Model):
name = models.CharField('Product Name', max_length=120, null=True)
class Meta:
db_table='Product'
def __str__(self):
return str(self.name)
class ReviewRating(models.Model):
user = models.ForeignKey(User,blank=True,on_delete=models.CASCADE)
product=models.ForeignKey(Product,related_name="comments", on_delete=models.CASCADE)
rating_1 = models.IntegerField(choices=RATING1,default=0)
def __str__(self):
return '%s - %s - %s'%(self.user, self.product, self.date_added)
Views
from django.db.models import Avg
def Notes (request, product_id):
product = Product.objects.get(pk=product_id)
data = Product.objects.order_by('name').annotate(
avg_rating_1 =Avg('comments__rating_1 '),
return render(request, 'main/notes.html',{'product':product, 'data':data})
Template
{% for ReviewRating in data%}
{{ReviewRating.avg_rating_1 }}
{% endfor %}
CodePudding user response:
Hello you should use aggregation and @property decorator to use this method as a field inside you project. Here example to your code.
class Product(models.Model):
name = models.CharField('Product Name', max_length=120, null=True)
class Meta:
db_table='Product'
def __str__(self):
return str(self.name)
@property
def rating(self):
rating = self.comments.aggregate(Avg('rating_1'))['rating_1__avg']
And inside your template you can use this like this:
{% for ReviewRating in champagnes %}
{{ReviewRating.rating_1 }}
{% endfor %}
Do not forget to import Avg
from django.db.models import Avg
CodePudding user response:
Solved.
All I needed to change the views from "order_by" to "filter(pk=product_id)".
I knew that was simple! (thanks for those who tried to help)
from django.db.models import Avg
def Notes (request, product_id):
product = Product.objects.get(pk=product_id)
data = Product.objects.filter(pk=product_id).annotate(
avg_rating_1 =Avg('comments__rating_1 '),
return render(request, 'main/notes.html',{'product':product, 'data':data})