I want to show an Average 5 Star rating in Django. Like in the picture below.
In the above image, there is an average rating of all users for a specific product and plus the Count of reviews.
Hence to store the rating to DB I used something code like this.
views.py
def product_detail(request, id):
product_detail = Product.objects.get(id=id)
review = Review.objects.filter(product = product_detail)
return render(request, 'detailpage/productdetail.html',
{'product_detail':product_detail, 'review':review})
review.html
<div class="container col-sm-7">
<form action="/product_review">
<input type="hidden" name="product_id" id="product_id" value="{{product.id}}">
<h4 style="font-weight:bold" class="mt-5">Create Review</h4>
<hr>
<h5 style="font-weight:bold">Overall Rating</h5>
<div class="stars">
<input class="star star-5" id="star-5" type="radio" name="rate" value="5" /> <label class="star star-5" for="star-5"></label> <input class="star star-4" id="star-4" type="radio" name="rate" value="4"/> <label class="star star-4" for="star-4"></label> <input class="star star-3" id="star-3" type="radio" name="rate" value="3"/> <label class="star star-3" for="star-3"></label> <input class="star star-2" id="star-2" type="radio" name="rate" value="2"/> <label class="star star-2" for="star-2"></label> <input class="star star-1" id="star-1" type="radio" name="rate" value="1rate"/> <label class="star star-1" for="star-1"></label>
</div>
<h5 style="font-weight:bold">Add a headline</h5>
<input type="text" name="subject" class="form-control" id="inputDefault" autocomplete="off">
<br>
<h5 style="font-weight:bold">Add a written review</h5>
<textarea class="form-control" name="comment" id="exampleTextarea" rows="3"></textarea>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
models.py
class Review(models.Model):
user = models.ForeignKey(User, models.CASCADE)
product = models.ForeignKey(Product, models.CASCADE,null=True, blank=True)
subject = models.CharField(max_length = 100, null=True, blank=True)
comment = models.TextField(max_length=250, null=True, blank=True)
rate = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.id)
I want to show Average Review in this code
<div class="review-feedback">
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
</div>
你可以使用 annotate......Review.objects.filter().annotate(avg=AVG(field))
Got solution for average rating:
First of all, I have to make changes to models.py where the product models are created and after changes the models look like this:
models.py
class Product(models.Model):
.
.
.
def averagereview(self):
review = Review.objects.filter(product=self).aggregate(avarage=Avg('rate'))
avg=0
if review["avarage"] is not None:
avg=float(review["avarage"])
return avg
def countreview(self):
reviews = Review.objects.filter(product=self).aggregate(count=Count('id'))
cnt=0
if reviews["count"] is not None:
cnt = int(reviews["count"])
return cnt
def __str__(self):
return str(self.id)
class Review(models.Model):
user = models.ForeignKey(User, models.CASCADE)
product = models.ForeignKey(Product, models.CASCADE,null=True, blank=True)
subject = models.CharField(max_length = 100, null=True, blank=True)
comment = models.TextField(max_length=250, null=True, blank=True)
rate = models.IntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.id)
and after that, I have to modify my HTML
page
product.html
<div class="review-feedback">
<span class="fa fa-star {% if product_detail.averagereview > 0 %} checked {% endif %}"></span>
<span class="fa fa-star {% if product_detail.averagereview > 1 %} checked {% endif %}"></span>
<span class="fa fa-star {% if product_detail.averagereview > 2 %} checked {% endif %}"></span>
<span class="fa fa-star {% if product_detail.averagereview > 3 %} checked {% endif %}"></span>
<span class="fa fa-star {% if product_detail.averagereview > 4 %} checked {% endif %}"></span>
{{product_detail.averagereview | stringformat:".2f"}}
</div>
views.py
def product_detail(request, id):
product_detail = Product.objects.get(id=id)
review = Review.objects.filter(product = product_detail)
return render(request, 'detailpage/productdetail.html',
{'product_detail':product_detail, 'review':review})
def product_review(request):
user = request.user
product_id = request.GET.get('product_id')
product_review = Product.objects.get(id=product_id)
subject = request.GET.get('subject')
comment = request.GET.get('comment')
rate = request.GET.get('rate')
Review(user=user, product=product_review, subject=subject, comment=comment, rate=rate).save()
return redirect('main:product-detail',id=product_id)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.