Search code examples
djangodjango-formsdjango-templatesdjango-viewsdjango-generic-views

How to pass a form view to another view as a context in django?


I'm using Django 1.8 to create an application. I have a Link model and a Comment model which has Link as a ForeignKey. I'm using generic views to generate a LinkDetailView and CommentCreateView and show them in separate template files and then include comment in link detail template. Here is the code:

views.py

class LinkDetailView(DetailView):
    models      = Link
    queryset    = Link.objects.all()

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

class CommentCreateView(CreateView):
    form_class  = CommentForm
    template_name = "comments/comment_form.html"


    def form_valid(self, form):
        link = get_object_or_404(Link, pk=form.data["link"] )
        f = form.save(commit=False)
        f.user = self.request.user
        f.link = link
        f.save()
        return super(CommentCreateView, self).form_valid(form)

link_detail.html

{% block content %}
 . . . 
{% include "comments/comment_form.html" %}
{% endblock %}

comment_form.html

<h2>Add Comment</h2>
<form action="" method="POST">
    {% csrf_token %}
    <table>
        {{ form.as_p }}
    </table>
    <input type="submit" name="submit" value="Submit" />
</form>

The form shows up in the link detail page but when I click submit button it goes to nowhere [I see error "POST /links/1/slug/ HTTP/1.1" 405 0 in shell] and obviously doesn't save in database.

I'm not sure if I've chosen correct approach to do this, so any help would be appreciated.


Solution

  • I've solved the problem using FormMixin here's the docs

    and here's how the views.py looks like now:

    class LinkDetailView(FormMixin, DetailView):
        models      = Link
        queryset    = Link.objects.all()
    
        form_class  = CommentForm
    
        def get_success_url(self):
            return reverse('link_detail', kwargs={'pk': self.object.pk, 'slug': self.object.slug})
    
        def get_context_data(self, **kwargs):
            context = super(LinkDetailView, self).get_context_data(**kwargs)
            context['form'] = self.get_form()
            return context
    
        def post(self, request, *args, **kwargs):
            if not request.user.is_authenticated():
                return HttpResponseForbidden()
            self.object = self.get_object()
            form = self.get_form()
            if form.is_valid():
                return self.form_valid(form)
            else:
                return self.form_invalid(form)
    
        def form_valid(self, form):
            link = get_object_or_404(Link, pk=self.object.pk)
            print link
            f = form.save(commit=False)
            f.user = self.request.user
            f.link = link
            f.save()
            return super(LinkDetailView, self).form_valid(form)