My django form is not working when i iterate through it using for loop

Viewed 514

Basically if I tried to use this code

{% for field in form %}

        <div class="input">
        <label for="" class="labelinput">{{field.label}}</label>
        {{field}}
        </div>

{% endfor %}

the form data wont make it pass is_valid().But it renders out the form fine. and if I use this code

<form action="" method="post"> {% csrf_token %}
 {{form}}
<input type="submit" value="">

it worked perfectly fine. How do I get the first code to work because I want to add classes between the label and the input field

and here's my view

def booklist_view(request):
    
  bkff = BookListForm()
  
  if request.method == 'POST':

      bkff = BookListForm(request.POST)

      if bkff.is_valid():
         
          bkff.save()
          bkff = BookListForm()

  context = {
      'form': bkff,
      
     
  }
  return render(request, 'booklist1st/booklist.html', context)
3 Answers

Please try this.

views.py

def booklist_view(request):
  form = BookListForm(request.POST or None)
  if request.method == 'POST':
      if form.is_valid(): 
          form.save()      
  context = {'form': form }
  return render(request, 'booklist1st/booklist.html', context)

Here we render field according according to field type(hidden_fields,visible_fields).

html template:

<form method="post">
    {% csrf_token %}
    {% for hidden in form.hidden_fields %}
      {{ hidden }}
    {% endfor %}
    {% for field in form.visible_fields %}
       <div class="input">
         {{field.label}}
         {{field}}
       </div>
    {% endif %}
    <input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>

You need to specify each field relate data like for=, id=, etc. To have maximum control over how your form is rendered, specify each field and control its style, for example, as we can't see your Form definition, this is an example on how it would be for a title field:

<form method="post">{% csrf_token %}
    {# Include the hidden fields #}
    {% for hidden in form.hidden_fields %}
    {{ hidden }}
    {% endfor %}
    {# Include the visible fields #}
    {{ form.non_field_errors }}

    {{ form.title.errors }}
    <label for="{{ form.title.id_for_label }}">Title</label>
    {{ form.title }}
    {% if form.title.help_text %}
    <small id="titleHelp">{{ form.title.help_text|safe }}</small>
    {% endif %}
    </div>

    <input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
    <form method="post">
        {% csrf_token %}
        {% for hidden in form.hidden_fields %}
          {{ hidden }}
        {% endfor %}
        {% for field in form.visible_fields %}
           <div class="input">
             <label for="" class="label">{{field.label}}</label>
             {{field}}
           </div>
        {% endfor %}
        <input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
    </form>

View.py

 from django.views.decorators.csrf import csrf_protect
    
    @csrf_protect
    def booklist_view(request):
        
      bkff = BookListForm()
      
      if request.method == 'POST':
          bkff = BookListForm(request.POST)
          if bkff.is_valid():  
              bkff.save()
      context = {
          'form': bkff,
      }
      return render(request, 'booklist1st/booklist.html', context)
Related