I am creating a web store using Django. i want to have a page displays a chosen product and within that page i want to see all the comment related to that specific product and also want to have a form for customers to add new comment for the product. I used class-based list-view and detail-view but the problems are 1- i could not displays related comments using class-based views(actually i could display it by creating a query_set and using template tags) 2- i could not render add new comment form into my template here is my code
models.py
class Goods(models.Model):
goods_main_band = models.ForeignKey(
MainBranch, to_field='mb_code', on_delete=models.CASCADE,
verbose_name='کد دسته اصلی', default=0
)
goods_sub_band1 = models.ForeignKey(
SubBranch1, to_field='sb1_code', on_delete=models.CASCADE,
verbose_name='کد دسته فرعی 1', default=0
)
goods_sub_band2 = models.ForeignKey(
SubBranch2, to_field='sb2_code', on_delete=models.CASCADE,
verbose_name='کد کالا', default=0
)
goods_properties = models.OneToOneField(
GoodsProperties, on_delete=models.CASCADE,
verbose_name='مشخصات کالا', null=True, blank=True
)
goods_specifications = models.OneToOneField(
GoodsSpecification, on_delete=models.CASCADE,
verbose_name='معرفی کالا', default=0, null=True, blank=True
)
name = models.CharField(verbose_name='نام کالا')
image = models.ImageField(upload_to='photos/%Y/%m/%d', null=True, blank=True, verbose_name='تصویر کالا')
quantity = models.PositiveIntegerField(default=0, verbose_name='تعداد موجود')
price = models.DecimalField(
decimal_places=0, max_digits=12, default=0,
verbose_name='قیمت کالا'
)
discount = models.SmallIntegerField(null=True, blank=True, verbose_name='میزان تخفیف')
seller = models.ManyToManyField('Seller', verbose_name='کد فروشنده')
def __str__(self):
return self.name
class Comments(models.Model):
goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='کد کالا')
customer = models.ForeignKey(CustomUser, on_delete=models.CASCADE, verbose_name='کد مشتری',)
vote_text = models.TextField(verbose_name='متن نظر')
vote_point = models.SmallIntegerField(null=True, blank=True, verbose_name='رای', help_text='متن نظر را وارد کنید')
vote_date = models.DateTimeField(auto_now=True, verbose_name='تاریخ ثبت رای')
def __str__(self):
return self.vote_text
views.py
class GoodsListView(ListView):
model = Goods
template_name = 'goods_list.html'
"""
we gather all kind of details about a specific good in goods_detail method such as comment and person
who leaves it for that good,a brif intro and criticizes about a product
"""
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['detail'] = Goods.objects.filter(id=self.kwargs['pk']).values()
context['comment'] = Comments.objects.filter(goods=self.kwargs['pk']).\
values('goods', 'customer', 'vote_text').order_by('customer')
context['customer'] = CustomUser.objects.filter(id__in=
Comments.objects.filter(goods=self.kwargs['pk']).values('customer'))\
.values('id', 'first_name', 'last_name').order_by('id')
context['goods_main_band'] = MainBranch.objects.filter(mb_code__in=
Goods.objects.filter(id=self.kwargs['pk']).values('goods_main_band_id')).values('main_desc')
context['goods_sub_band1'] = SubBranch1.objects.filter(sb1_code__in=
Goods.objects.filter(id=self.kwargs['pk']).values('goods_sub_band1_id')).values('sb1_desc')
context['goods_specification'] = GoodsSpecification.objects.filter(goods_sub_band2__in=
Goods.objects.filter(id=self.kwargs['pk']).values('goods_sub_band2_id')).values('spec_desc')
context['goods_properties'] = GoodsProperties.objects.filter(goods_sub_band2__in=
Goods.objects.filter(id=self.kwargs['pk']).values('goods_sub_band2_id'))\
.values('goods_intro', 'goods_criticize')
return context
class GoodsDetailView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
view = CommentGet.as_view()
return view(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
view = CommentPost.as_view()
return view(request, *args, **kwargs)
class CommentGet(DetailView):
model = Comments
template_name = "goods_detail.html"
# def get_object(self, queryset=None):
# return Goods.objects.get(pk=self.kwargs.get('pk'))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form"] = CommentForm()
return context
class CommentPost(SingleObjectMixin, FormView):
model = Comments
form_class = CommentForm
template_name = 'goods_detail.html'
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super().post(request, *args, **kwargs)
def form_valid(self, form):
comment = form.save(commit=False)
self.object = self.get_object()
comment.goods = self.object
comment.save()
return super().form_valid(form)
def get_success_url(self):
goods = self.get_object()
return reverse("goods_detail", kwargs={"pk": goods.pk})
urls.py
urlpatterns = [
path('about/', AboutPageView.as_view(), name='about'),
path('?/', GoodsSearchView.as_view(), name='gsview'),
path('?/<int:pk>/', GoodsListView.as_view(), name='goods_list'),
path('?/<int:pk>/comment', GoodsDetailView.as_view(), name='goods_detail'),
]
good_list.html
{% extends '_base.html' %}
{% load static %}
{% load goods_extras %}
{% load crispy_forms_tags %}
{% block title %}
{% for item in detail %}
{{item.name}}
{% endfor %}
{% endblock title %}
{% block content %}
# here goes the code that displays a product specification
<h4>نظرها</h4># here i can deisplay comments
{% for comment in comment %}
{% for customer in customer%}
<p>{{customer.first_name}} {{customer.last_name}} :: {{comment.vote_text}}</p>
{% endfor %}
{% endfor %}
<hr># but i want to use class-based approach to display comment
# and this piece of code would not work
<div class = "card-footer">
{% for comment in goods.comment_set.all %}
<p>
<span class = "font-weight-bold">{{comment.customer}} ·
</span>
{{comment.vote_text}}
</p>
{% endfor %}
</div>
</div>
{% endblock content %}
good_detail.html
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block title %}ثبت نظر {% endblock title %}
{% block content %}
<hr>
<h4>نظرها</h4># displayin comments(that does not work)
{% for comment in goods.comment_set.all %}
<p>{{ comment.customer }} · {{ comment.vote_text }}</p>
{% endfor %}
<hr>
<h4>افزودن نظر جدید</h4># form for getting users comment(does not work)
<form action = "" method="post">{% csrf_token %}
{{form|crispy}}
<button class = "btn btn-success ml-2" type="submit" >ذخیره</button>
</form>
<p>
<a href="">ویرایش</a> |
<a href="">حذف</a>
</p>
{% endblock content %}
any answer would be appreciated thanks
I tried using list-view and detail-view also reading a lot of pages but did not find anything useful
I want to have a page that displays a product and all related comment to the product and add new comment form in a single template