0

Hello guys I am making a ecommerce website as part of learning django. I have a review model but I want to make sure that a customer can only put a review once. How to do that with my existing model and views. Please have a look at my codes:

views

def product_review(request, slug):
    user = request.user
    product = get_object_or_404(Product, slug=slug)
    reviews = ProductFeedback.objects.filter(product=product).order_by('-id')
    if request.POST:
        if product.user == request.user:
            messages.error(request, 'You can\'t review your own product')
            return redirect('store:product_detail', product.slug)
        else:
            p_review_form = ProductReviewForm(request.POST or None)
            if p_review_form.is_valid():
                product_rating = request.POST.get('product_rating')
                product_review = request.POST.get('product_review')
                p_review = ProductFeedback.objects.create(product=product, user=user, 
                                            product_rating=product_rating, product_review=product_review)   
                p_review.save()
                return redirect('store:product_detail', product.slug)
    else:
        p_review_form = ProductReviewForm()

    context = {
        'product':product,
        'p_review_form':p_review_form,
        'reviews': reviews,
    }
    return render(request, 'store/product/product_detail.html', context)

model

class ProductFeedback(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='product')
product_rating = models.CharField(choices=RATINGS, max_length=10, null=True)
product_review = models.TextField(max_length=1000)
reply = models.ForeignKey('ProductFeedback', null=True, related_name='replies', blank=True, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return f'{self.user.username}--{self.product.title} review'
Danny
  • 287
  • 7
  • 30

1 Answers1

1

You can filter all reviews by the user if there is any review then raise an error. The main idea is to get the reviews and filter them by request.user and see if there are any.

from django.core.exceptions import PermissionDenied

def product_review(request, slug):
  product = get_object_or_404(Product, slug=slug)
  # Get the reviews posted by the user for this product
  user_review = Product.product.filter(user=request.user)

  if request.method == 'POST':
    if user_review:
      # If there is/are any reviews, raise an error
      raise PermissionDenied('You have already given your review on this post.')

Hope this helps.

Sheraram_Prajapat
  • 589
  • 1
  • 9
  • 27
  • Thank you. I made some changes to the code to make it work though. user_review = ProductFeedback.objects.filter(product=product, user=user) This worked fine. – Danny May 26 '20 at 18:17