The problem comes from the fact you don’t provide any pk
keyword argument to your view.
From the urls.py, I can see you have a slug kwargs though. You can then identify the matching product with its slug.
In your views.py, replace:
form.instance.product_id = self.kwargs['pk']
by
form.instance.product = Product.objects.get(slug=self.kwargs['slug'])
Explanation:
Here you want to associate your comment with the matching product. So, for that, you use NameOfModel.objects.get(query)
, which returns one single instance of your model (here Product), matching the query
. In your case the only way to retrieve the object is getting the keyword argument slug
from your url and search it on your Product slug field, so here the query is slug=self.kwargs['slug']
.
Hi everyone the comments are not working with CBV my form not even saving the comment. here is my code i will love if anyone help me with this.my models.py is
class Product(models.Model):
title = models.CharField(max_length=110)
slug = models.SlugField(blank=True, unique=True)
price = models.DecimalField(decimal_places=2, max_digits=6)
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 = models.CharField(max_length=1000)
featured = models.BooleanField(default=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
time_stamp = models.DateTimeField(auto_now_add=True)
objects=ProductManager()
def get_absolute_url(self):#i use this in product_list.html to go to detail page
#return "/product/{slug}".format(slug=self.slug)
return reverse("products:detail", kwargs={"slug" : self.slug})
def __str__(self):
return str(self.title)
@property
def name(self): #sometime in html i say name istead of title so to make it work i wrote this
return self.title
def product_pre_save_reciever(sender, instance, *args, **kwargs):#i inherit unique slug generator from utils to here so when i create aa new instance it slug automatically generate. and i i create two t shirts it give a random straing to tshirt 2nd slug
if not instance.slug:
instance.slug=unique_slug_generator(instance)
pre_save.connect(product_pre_save_reciever, sender=Product)
class Comment(models.Model):
product=models.ForeignKey(Product , related_name="comments", on_delete=models.CASCADE)
name = models.CharField(max_length=255)
body=models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s'%(self.product.title, self.name)
my forms.py is:
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['name', 'body']
widgets ={
'name':forms.TextInput(attrs={'class':'form-control'}),
'body':forms.Textarea(attrs={'class':'form-control'}),
}
the views.py is:
class CommentCreateView(CreateView):
model = Comment
form_class = CommentForm
template_name = 'add-comment.html'
# fields = '__all__'
def form_valid(self, form):
form.instance.product_id = self.kwargs['pk']
return super().form_valid(form)
success_url = reverse_lazy('list')
my add-comment.html is:
{% extends "base.html"%}
{% load crispy_forms_tags%}
{% block content %}
<h2 class="text-center">comment here...</h2>
<div class="col-md-6 offset-md-3">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
{{form|crispy}}
</fieldset>
<!-- <div class="form-group"><button class="btn btn-outline-info" type="submit">Pubmit</button>-->
<!-- </div>-->
<!-- <input type="submit" value="Submit" class="btn btn-secondary">-->
<button class="btn btn-secondary">Add comment</button>
</form>
</div>
{% endblock %}
and my urls.py is:
urlpatterns = [
# path('featured/' , ProductFeaturedListView.as_view()),
#path('featured/<int:pk>' , ProductFeaturedDetailView.as_view()),
path('' , ProductListView.as_view(), name= "list"),
path('new/' , ProductCreateView.as_view() , name="product-create"),
path('<slug:slug>/update/' , ProductUpdateView.as_view() , name="product-update"),
path('<slug:slug>/delete/' , ProductDeleteView.as_view() , name="product-delete"),
#path('product-fbv/' , product_list_view),
#path('product/<int:pk>' , ProductDetailView.as_view()),
path('<slug:slug>/comment' , CommentCreateView.as_view() , name="add-comment"),
path('<slug:slug>' , ProductDetailSlugView.as_view() , name="detail"),
# path('product-fbv/<int:pk>' , product_detail_view),
]
and the error comes when I hit post comment is:

sir actually i follow a tutorial from you tube. i know i should replace pk with slug but when i wrote slug it give me error key error slug instead of key error pk