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?
One option would be to use the DetailView for the Post and a templatetag to display the comment form. Have the comment form submit to a Comment CreateView that redirects to the DetailView on success.
That said, it might get a little ugly if the form is invalid. In a pinch you can always call a DetailView or its methods from one of the CreateView methods. But IMO that introduces more coupling rather than less. Or you could have a separate utility function that you can call from the CreateView to display the Post if the comment form has errors.
Another option would be to use AJAX to process the comment form (in the separate CreateView) instead of a new page load.
In the end, regardless of language or framework, there's going to be a limit to how much one can decouple a view that needs to display one object type and create another.