简体   繁体   中英

How to Show Average of Star Rating in django

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)

NOW

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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                {{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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM