Combining DetailView and CreateView in Django 1.6

Viewed 2965

I have 2 separate models, Post and Comment. I use DetailView to display Post contents and I want to use a CreateView to display comment creation form on the same page. What is the cleanest way to go about that?

The only thing that comes to mind is to use custom view which both gets an object and processes comment form, but this looks too dirty:

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)
    if request.POST:
        form = CommentForm(request.POST)
        # do comment form processing here
    return render(request, "post/post_detail.html", {
        "object": post, "comment_form": form})

Is there any clean way to do this using class based views? Or just some way to decouple post display code from comment processing code?

2 Answers

It is possible to combine DetailView and CreateView. You use a class for DetailView and another class for CreateView, then you create a new class that inherits from View. This new class has a get and post method. The get method calls the DetailView while the post method calls the CreateView. Take note to use reverse_lazy for the success_url in CreateView. So basically your code should look something like this:

class PostView(DetailView):
    # your code 
    pass ;

class CommentView(CreateView):
    def get_success_url(self):
        return reverse_lazy('post_detail', kwargs={'pk': self.get_object(Post.objects.all().pk})

class PostCommentView(View):
    def get(self, request, *args, **kwargs):
         view = PostView.as_view()
         return view(request, *args, **kwargs) 

    def post(self, request, *args, **kwargs) :
         view = CommentView.as_view()
         return view(request, *args, **kwargs) 

So your urls.py will point to

PostCommentView 

I did an override of get_success_url because it will try to go to the detail view of the new comment which doesn't exist and is not what you want to do. So the override will take you to the DetailView of the post instead.

There is an explanation in the documentation.

Related