How to preserve form fields in django after unsuccessful submit?

11,350

Solution 1

In your template you are not making use of form passed by the view.

You can update part of your template as (assuming your field names in the form are first_field and second_field.

<form action="/feedback/" method="POST">
    {% csrf_token %}
    <div class="article">
        <label for="name">
            Ваше имя:
        </label>
        <br />
        {{ form.first_field.errors }}
        {{ form.first_field.label_tag }}: {{ form.first_field }}
        <br />
        <!-- class="inputbox required" -->
        {{ form.second_field.errors }}
        {{ form.second_field.label_tag }}: {{ form.second_field }}
        <br />
        <input type="submit" name="submit" value="Отправить">
    </div> <!-- /article -->
</form>

For more reference - Displaying form using template

Solution 2

You need to pass the form back to the template; and you need to render the form in the template as per jpic's link.

The following should render your form errors:

from django.shortcuts import render, redirect

def feedback(request):
    ctx = {}
    ctx['articles'] = Comment.objects.all()
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/thanks')
        else:
            ctx['form'] = form
            return render(request, 'feedback.html', ctx)
    else:
        ctx['form'] = CommentForm()
    return render(request, "feedback.html", ctx)

In your template:

{% extends "base.html" %}
{% block main %}
    <table>
        <form action="/feedback/" method="POST">
            {% csrf_token %}
            <div class="article">
                {{ form }}
                <br />
                <input type="submit" name="submit" value="Отправить">
            </div> <!-- /article -->
        </form>
    </table>
    {% include "articles.html" %}
{% endblock %}

Solution 3

Easy, your template has this:

<input type="text" name="name" id="name" size="40" class="inputbox" value="" />

So value attribute of the input tag is always empty.

Same goes for the textarea, which should always render empty:

<textarea class="WithoutTinymce" cols="50" rows="10" name="text" id="text"></textarea>

Check out the documentation about rendering a form in a template

Share:
11,350
DSblizzard
Author by

DSblizzard

Evgeny Luttsev. Mathematician (P vs NP), programmer (programming language design, natural language programming). Email: dsblizzard % gmail % com

Updated on June 15, 2022

Comments

  • DSblizzard
    DSblizzard almost 2 years

    Code from views.py:

    def feedback(request):
        if request.method == "POST":
            form = CommentForm(request.POST)
            if form.is_valid():
                form.save()
            else:
                print("form.errors:", form.errors)
        else:
            form = CommentForm()
        articles = Comment.objects.all()
        ResponseDict = {"articles": articles, "form": form}
        return render_to_response("feedback.html", ResponseDict, 
            context_instance = RequestContext(request))
    

    I've tried this and several modifications from answers to similar questions, but nothing works. When I press submit button, all form fields in html become empty.

    EDIT: code from feedback.html:

    {% extends "base.html" %}
    {% block main %}
        <table>
            <form action="/feedback/" method="POST">
                {% csrf_token %}
                <div class="article">
                    <label for="name">
                        Ваше имя:
                    </label>
                    <br />
                    <input type="text" name="name" id="name" size="40" class="inputbox" value="" />
                    <br />
                    <!-- class="inputbox required" -->
                    <textarea class="WithoutTinymce" cols="50" rows="10" name="text" id="text"></textarea>
                    <br />
                    <input type="submit" name="submit" value="Отправить">
                </div> <!-- /article -->
            </form>
        </table>
        {% include "articles.html" %}
    {% endblock %}
    

    I can also paste code from base.html if needed.

    EDIT2: minimized code from base.html:

    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs" lang="cs">
    ...
    <body id="body-id" onload="loaded()">
    
    <!-- Main -->
    <div id="main" class="box">
        <div id="page" class="box">
            <div id="page-in" class="box">
                <!-- Content -->
                <div id="content">
                    {% block main %}
                    {% endblock %}
                    <hr class="noscreen" />
                </div> <!-- /content -->
            </div> <!-- /page-in -->
        </div> <!-- /page -->
    </div> <!-- /Main -->
    </body>
    </html>