content from two models and a submission from all in one template

Hi every one
I have two model one for storing the product specification and the other for comments for products
what i want to do is to have a template that:

  • displays all of a certain product specification
  • displays all comment related to that certain product
  • have a form for submitting new comment
    is it possible to have all above feature in one template?
    any help would be appreciated.

Yes it is possible

I’ll provide you some context data related to your query

# Models

class Product(Model):
    ....

    @property
    def get_comments(self):
        product_comments = self.product_comments.all()
        return product_comments


class ProductComments(Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="product_comments")
    ....

So what I did here is created two models as you can see and in ProductComments model there is a ForeignKey of product with related_name="product_comments". it is very important. Than in Product model there is a property method which will retrieve all the comments from ProductComments for a specific product.
You can use it in your template or even in your REST APIs.

thanks for your answer
now all comments displays in my template
one other thing i want to do in this template is having a form i by witch a user can leave a comment
actualy here is my views.py

class GoodsListView(DetailView):
    model = Goods 
    template_name = 'goods_list.html'   

    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})

and 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'),
]

i can reach new comment page by adding /comment at thr end of url but i want to display comment form in product page

which one of them is the view you are talking about ?

GoodsListView is the one

Okay so in your get_context_data method pass the form as well if you have created a comment form in your forms.py else continue to next part

Now from your template whenever you submit a form it will send form data to your view, for this you can use GoodsListView here just create a post method and handle every part in it.

class GoodsListView(DetailView):
    .....

    def post(self, request):
        ....

also in the template in your form tag use action as . i.e

<form method="post" action=".">
     ...
</form>

Thanks for your help it worked

Now i have another problem updating/deleting commens

i wrote update/delete view as follow but i get 'page not found ’ error

updateview

class CommentUpdate(UserPassesTestMixin, LoginRequiredMixin, UpdateView):
    model = Comments
    form_class = CommentForm
    template_name = 'edit_comment.html'
    fields = ['vote_text']
    success_url = 'goods_list'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        self.object = self.get_object()
        context['obj'] = self.object
        context['form'] = CommentForm
        return context

    def test_func(self):
        obj = self.get_object()
        return obj.customer == self.request.user

delete view

class CommentDelete(UserPassesTestMixin, LoginRequiredMixin, DeleteView):
    model = Comments
    template_name = 'delete_comment.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data()
        context['g_name'] = Goods.objects.filter(id=self.kwargs['pk']).values('name')
        context['g_comment'] = Comments.objects.filter(goods=self.kwargs['pk']). \
            values('vote_text').order_by('customer')
        return context

    def test_func(self):
        obj = self.get_object()
        return obj.customer == self.request.user

urls.py

from django.urls import path
from .views import GoodsSearchView, AboutPageView, GoodsListView, CommentUpdate, CommentDelete

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>/edit_comment/', CommentUpdate.as_view(), name='edit_comment'),
    path('?/<int:pk>/delete_comment/', CommentDelete.as_view(), name='delete_comment'),
]

here is error