1

I have two class inside my model and these two models are :

from django.db import models
from accounts.models import *
from django.core.validators import MinValueValidator, MaxValueValidator
# Create your models here.
class Products(models.Model):
    name = models.CharField(max_length=50)
    img = models.ImageField(upload_to='productImage')
    CATEGORY = (
        ('Snacks','Snacks'),
        ('Juice','Juice'),
    )
    category = models.CharField(max_length=50, choices=CATEGORY)
    description = models.TextField()
    price = models.FloatField()
    review = models.TextField()

    def no_of_rating(self):
        rating = Rating.objects.filter(product=self)
        return len(rating)

    def avg_rating(self):
        sum = 0
        ratings = Rating.objects.filter(self)
        for rating in ratings:
            sum += rating
            if len(ratings>0):
                return sum//len(rating)
            else:
                return 0  

    rating = avg_rating(self) # This Line did not work for me

    def __str__(self):
        return self.name



class Rating(models.Model):
    product = models.ForeignKey(Products, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    stars = models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)])

    def __str__(self):
        return str(self.product)+"---"+str(self.user)



# Views Code
def products(request):
    product = Products.objects.all()
    content = {
        'Products':product,
    }
    return render(request,'products.html',content)




#Template Code
{% for product in Products %}
<div class="col-xs-12 col-md-6">
    <!-- First product box start here-->
    <div class="prod-info-main prod-wrap clearfix">
        <div class="row">
                <div class="col-md-5 col-sm-12 col-xs-12">
                    <div class="product-image"> 
                        <img src="{{product.img.url}}" class="img-responsive rotprod"> 

                    </div>
                </div>
                <div class="col-md-7 col-sm-12 col-xs-12">
                <div class="product-deatil">
                        <h5 class="name">
                            <a href="#">
                                {{product.name}}
                            </a>
                            <br>
                            <a href="#">
                                <span>{{product.category}}</span> <br>
                                <span>{{product.avg_rating}}</span> <br>
                            </a>                            

                        </h5>
                        <p class="price-container">
                            <span>₹{{product.price}}</span>
                        </p>
                        <span class="tag1"></span> 
                </div>
                <div class="description">
                    <p>{{product.description}}</p>
                </div>
                <div class="product-info smart-form">
                    <div class="row">
                        <div class="col-md-12"> 
                            <a href="javascript:void(0);" class="btn btn-danger btn-cart"><span>Add to cart</span></a>
                            <a href="javascript:void(0);" class="btn btn-info"><span>More info</span></a>
                        </div>

                        <!--
                        <div class="col-md-12">
                            <div class="rating">Rating:
                                <label for="stars-rating-5"><i class="fa fa-star text-danger"></i></label>
                                <label for="stars-rating-4"><i class="fa fa-star text-danger"></i></label>
                                <label for="stars-rating-3"><i class="fa fa-star text-danger"></i></label>
                                <label for="stars-rating-2"><i class="fa fa-star text-warning"></i></label>
                                <label for="stars-rating-1"><i class="fa fa-star text-warning"></i></label>
                            </div>
                        </div>
                    -->
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- end product -->
</div>
{% endfor %}


I want to store the average rating of the product in the Product model/table, how can I perform this operation as I am not able to doing that by my code manly by calling that function. How to store each product's average value in the product module.

and while I am trying to resolve it by directly calling the method of that product model am getting this below error: "TypeError at /products 'Products' object is not iterable"

template error

3 Answers3

1

If you want to store the avg. rating in a database, you need to make it a field, not a function. You could do something like this:

class Products(models.Model):
    # ...
    average_rating = models.IntegerField()

    # Override the save method
    def save(self, force_insert=False, force_update=False):
        average_rating = # calculate the average rating
        self.average_rating = average_rating
        super(Products, self).save(force_insert, force_update)
Simon Martineau
  • 210
  • 2
  • 8
0

It's not impossible to have the average rating as a field, but it's not commonly done. You should keep the avg_rating method and just refer to it when needed, i.e. in your template you can call {{ product.avg_rating }}

0sVoid
  • 2,547
  • 1
  • 10
  • 25
0
class Product(models.Model):
  title = models.CharField(max_length=255)

  slug = models.SlugField(null=False, unique=True)

      
  def myrating(self):
     myvalue = self.ratingproduct.aggregate(Avg('rating'))
     return myvalue

class Review(models.Model):
   fullname = models.CharField(max_length=200)

   rating = models.IntegerField()

   product = models.ForeignKey(Product, related_name="ratingproduct", 
             on_delete=models.CASCADE, blank=True, null=True)

   def __str__(self):
       return self.fullname

and in template call value by using: {{product.myrating.rating__avg}} here product = get_object_or_404(Product, category__slug=category_slug, slug=product_slug)