Search code examples
djangodjango-class-based-viewsdjango-3.0

How to render form with class-based view?


I have an index page:

views.py

class IndexView(TemplateView):
    template_name = "index.html"

urls.py

urlpatterns = [
    path('', IndexView.as_view()),
]

And I need to render form in this page

index.html

{% block content %}
    <!-- Other blocks -->
    <div id="input">
        <form method="POST" class="text-form">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit" class="submit btn">Submit</button>
        </form>
    </div>
    <!-- Other blocks -->
{% endblock %}

forms.py

class TextForm(forms.Form):
    text = forms.CharField(widget=forms.Textarea)

There is a topic about class-based views forms handling but it is not clear for me how to render HTML with this form


Solution

  • Right now you do not pass a form to the context. You can make use of a FormView [Django-doc] or other views that use a form like a CreateView [Django-doc], UpdateView [Django-doc], etc.

    You thus can define a FormView and set the form_class attribute [Django-doc] to the class you wish to render:

    # app/views.py
    
    from app.forms import TextForm
    from django.views.generic.edit import FormView
    
    class IndexView(FormView):
        template_name = 'index.html'
        form_class = TextForm

    @PavelAntspovich: if it makes a post, it will automatically construct the form and pass the request.POST and request.FILES to it, and check if it is valid. If it is, it will call the form_valid method [Django-doc] with the form as parameter. If not, it will call the form_invalid method [Django-doc]. These methods need to return a HttpResponse (that is then the result of the view).