Prevent repetition code in methods get and post in django class vase view

There are several lines of code in the get method that are also used in the post method. How can I prevent code repetition in this view?

class ProductDetail(View):
    def get(self, request, *args, **kwargs):
        products = Product.objects.get(id=self.kwargs['pk'])
        related_products = products.tags.similar_objects()[:4]
        comments = Comment.objects.filter(is_reply=False, product_id=self.kwargs['pk'])
        change = Chart.objects.filter(product_id=self.kwargs['pk'])

        context = (
            {'products': products, 'related_products': related_products, 'comments': comments, 
             'change': change})
        return render(request, 'home/details.html', context)

    def post(self, request, *args, **kwargs):
        products = Product.objects.get(id=self.kwargs['pk'])
        related_products = products.tags.similar_objects()[:4]
        comments = Comment.objects.filter(is_reply=False, product_id=self.kwargs['pk'])
        change = Chart.objects.filter(product_id=self.kwargs['pk'])
        
        context = ({'products': products, 'related_products': related_products, 'comments': comments, 
                    'change': change})
        return render(request, 'home/details.html', context)

Does this work ?

class ProductDetail(View):
    def dostuff(id):
        self.products = Product.objects.get(id)
        self.related_products = self.products.tags.similar_objects()[:4]
        self.comments = Comment.objects.filter(is_reply=False, product_id=id)
        self.change = Chart.objects.filter(product_id=id)        

    def get(self, request, *args, **kwargs):
        dostuff(self.kwargs['pk'])
        context = (
            {'products': self.products, 'related_products': self.related_products, 'comments': self.comments, 
             'change': self.change})
        return render(request, 'home/details.html', context)

    def post(self, request, *args, **kwargs):
        dostuff(self.kwargs['pk'])
        context = ({'products': self.products, 'related_products': self.related_products, 'comments': self.comments, 
                    'change': self.change})
        return render(request, 'home/details.html', context)

You can simply use DetailView from DGCBV.

class ProductDetail(DetailView):
    model = Product
    template_name = 'home/details.html'

    def post(self, request, *args, **kwargs):
        return self.get(request, *args, **kwargs)

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        obj = context['products'] = context['product']
        context['related_products'] = obj.tags.similar_objects()[:4]
        context['comments'] = Comment.objects.filter(is_reply=False, produc=obj)
        context['change'] = Chart.objects.filter(product=obj)
        return context

if you rename you template to product_detail.html, you can remove template name attribute.

By the way: if you have only single product, why you named it "products" ?

Back to Top