问题
This is my first Django app. I am trying to display an average rating from multiple reviews.
This seems to work in my product template but not on my blog template because productprofile_id is not defined:
product_rating = Review.objects.filter(product_id=productprofile_id).aggregate(Avg('rating')).values()
How do I filter the Review model with the related_products field in the Blog model? Or is it possible to just include the product view in my Post template? Thanks in advance for your help!
my models:
class Post(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=100)
related_product = models.ManyToManyField(ProductProfile, blank=True)
def __str__(self):
return self.title
class ProductProfile(models.Model):
product = models.CharField(max_length=80)
avatar = models.ImageField(upload_to='profile_images', blank=True)
price = models.IntegerField()
info = models.TextField(blank=True)
category = models.ForeignKey(ProductCategories)
link = models.URLField(blank=True)
bookmarks = models.ManyToManyField(User, blank=True,related_name='product_bookmarks')
def __str__(self):
return self.product
class Review(models.Model):
user = models.ForeignKey(User)
product = models.ForeignKey(ProductProfile)
rating = models.IntegerField()
review = models.TextField(blank=True)
def __str__(self):
return self.user.username
My views:
def post(request, post_id):
try:
post = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
raise Http404
product_rating = Review.objects.filter(product_id=productprofile_id).aggregate(Avg('rating')).values()
return render(request, 'app/blog.html', {'post': post, 'product_rating': product_rating})
def product(request, productprofile_id):
try:
product = ProductProfile.objects.get(pk=productprofile_id)
except ProductProfile.DoesNotExist:
raise Http404
product_media = ProductMedia.objects.filter(product_id=productprofile_id)
product_brand = BrandProfile.objects.filter(products__id=productprofile_id)
review = Review.objects.filter(product_id=productprofile_id)
product_rating = Review.objects.filter(product_id=productprofile_id).aggregate(Avg('rating')).values()
return render(request, 'app/product.html', {'product': product, 'product_media': product_media, 'review': review, 'product_rating': product_rating, 'product_brand': product_brand,})
My template tag:
{% for value in product_rating %} {{ value }} {%endfor%}
回答1:
I think you should make the rating a method on the ProductProfile model, which returns the average of the reviews for that product:
class ProductProfile(models.Model):
...
def avg_rating(self):
return self.review_set.aggregate(Avg('rating')).values()
Now you can remove it from both views, and call {{ product.avg_rating }}
when you iterate through the products in the post view.
回答2:
Maybe
{% for productprofile in post.related_product_set.all %}
{{ productprofile.review.rating }}
{% endfor %}
? I can't remember if the .all is required.
来源:https://stackoverflow.com/questions/31702487/django-filter-a-model-with-a-field-from-another-model