I want my reviews that are on that particular product to be shown only on that product not on any other . I do not know how to filter it. Recently it is showing all the reviews on every product.
My models.py file is:
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Product , on_delete=models.CASCADE, null=True)
date = models.DateTimeField(auto_now_add=True)
text = models.TextField(max_length=3000 , blank=True)
rate = models.PositiveSmallIntegerField(choices=RATE_CHOICES)
likes= models.PositiveIntegerField(default=0)
dislikes = models.PositiveIntegerField(default=0)
def __str__(self):
return self.user.full_name
my product models.py is:
class Product(models.Model):
title = models.CharField(max_length=110)
slug = models.SlugField(blank=True, unique=True)
status = models.CharField(choices=CATEGORY_CHOICES, max_length=10)
price = models.DecimalField(decimal_places=2, max_digits=6)
quantity=models.IntegerField(default=1)
discount_price=models.FloatField(blank=True, null=True)
size = models.CharField(choices=SIZE_CHOICES, max_length=20)
color = models.CharField(max_length=20, blank=True, null=True)
image = models.ImageField(upload_to=upload_image_path)
description = RichTextField(max_length=1000)
featured = models.BooleanField(default=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
time_stamp = models.DateTimeField(auto_now_add=True)
my product detail views.py is:
class ProductDetailSlugView(ObjectViewedMixin,DetailView):
queryset = Product.objects.all()
context_object_name = "object_list"
template_name = "product_detail.html"
def get_context_data(self, *args ,**kwargs):
context = super(ProductDetailSlugView , self).get_context_data(*args, **kwargs)
context['reviews'] = Review.objects.all()
# context['reviews'] = Review.objects.filter(product=self.request.product)
cart_obj, new_obj = Cart.objects.new_or_get(self.request)
context['cart'] = cart_obj
# context['comments'] = Comment.objects.all()
return context
my product_detail.html is:
<!-- {% for review in reviews %}-->when i do this with my code it show me all the product
<!-- <h1>{{review.text}}{{review.rate}}</h1>-->
<!-- {% endfor %}-->
{% for review in product.review_set.all %}
{{ review.text }}
{% endfor %}
You do not need to make a query separately for your reviews. You can simply loop over them using your instance of Product
in the template. Also for some reason you have set context_object_name = "object_list"
try this:
{% for review in object.review_set.all %}
{{ review.text }}
{% endfor %}
Here review_set
is simply the default related_name
set by Django which is the related models name in lowercase with _set
appended to it. You can chose to set the related name yourself like so if you want:
product = models.ForeignKey(Product, related_name='reviews', on_delete=models.CASCADE, null=True)
Anyway if you insist on modifying the view you can simply do this:
class ProductDetailSlugView(ObjectViewedMixin,DetailView):
queryset = Product.objects.all()
context_object_name = "object_list"
template_name = "product_detail.html"
def get_context_data(self, *args ,**kwargs):
context = super(ProductDetailSlugView , self).get_context_data(*args, **kwargs)
context['reviews'] = Review.objects.filter(product=self.object)
cart_obj, new_obj = Cart.objects.new_or_get(self.request)
context['cart'] = cart_obj
# context['comments'] = Comment.objects.all()
return context
And then you can use this:
{% for review in reviews %}
{{ review.text }}
{% endfor %}