displaying a product and all related comment to the product and add new comment form in a single template

34 Views Asked by At

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}} &middot;
            </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 }} &middot; {{ 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

0

There are 0 best solutions below