Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django formset not validating because ID is required

MY view receives a model formset from the template, but it doesn't pass validation, claiming that ID is required. Al my use of forms until now has never brought up this problem, and I've never had to pass ID's around.

Here is a simplified version of my view:

def BudgetView(request):

    import pdb
    pdb.set_trace()

    if request.user.is_authenticated:
        U=request.user

        #initalize formset factories
        ItemFormSet = modelformset_factory(Item, fields=(blabla), extra=0)
        CatFormset=modelformset_factory(BudgetCatagory, fields=(blabla), extra=0)

        #initalize Constants
        InitiateConstants(CatagoryItemsList)

        if request.method=='POST':
            FormsetItem=ItemFormSet(request.POST,initial=Item.objects.filter(budgetcatagory__user_id=U.id).values())
            FormsetCat=CatFormset(request.POST)
            if FormsetItem.is_valid():
-bla
-bla
-bla

            return redirect('/HighLevelInput')
        else:
            #populate
            I=Item.objects.filter(budgetcatagory__user_id=U.id)
            C=BudgetCatagory.objects.filter(user_id=U.id)

            #initiate initial catagories and items for new user
            if (not I.exists()) or (not C.exists()):
                Item.objects.filter(budgetcatagory__user_id=U.id).delete()
                BudgetCatagory.objects.filter(user_id=U.id).delete()
                InitiateNewUser(U)
                I=Item.objects.filter(budgetcatagory__user_id=U.id)
                C=BudgetCatagory.objects.filter(user_id=U.id)
            FormsetItem=ItemFormSet(queryset=I)
            FormsetCat=CatFormset(queryset=C)

        return render(request,'getdata/budgetmachine.html', {'FormsetItem':FormsetItem, 'FormsetCat':FormsetCat })
    else:
        return redirect('/login')

is_valid returns False for the reason I've mentioned above. any ideas?

As requested, here are the errors returned from the is_valid check:

(Pdb) FormsetItem.errors
[{'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'name': ['This field is required.'], 'detail': ['This field is required.'], 'layout': ['This field is required.'], 'unit': ['This field is required.'], 'unit_description': ['This field is required.'], 'parent': ['This field is required.'], 'enName': ['This field is required.'], 'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'name': ['Ensure this value has at most 30 characters (it has 32).'], 'parent': ['Ensure this value has at most 30 characters (it has 32).'], 'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}, {'id': ['This field is required.']}]

And here is my template:

{% block body %}

<div class="container" style="width:80%">

  <form method="post">
    {% csrf_token %}
    {{ FormsetItem.management_form }}
    {{ FormsetCat.management_form }}

    <table>
      <tr>
        <th>פריט</th>
        <th>מחיר מתוקצב</th>
        <th>מיקום מחיר</th>
        <th>רמת פירוט</th>
        <th>רמת פירוט</th>
      </tr>

      <!--unpacks the item dictionary into formsets -->
      {% for CatForm in FormsetCat %}
        <tbody onmouseenter="ToggleDisable('{{ CatForm.enName.value}}')" onmouseleave="ToggleDisable('{{ CatForm.enName.value}}')">
          {% for ItemForm in FormsetItem %}
            {% if ItemForm.parent.value == CatForm.name.value %}
                {% if ItemForm.layout.value == 'normal' %}
                  {% include 'getdata/normalBudgetLayout.html' with form=ItemForm itemCount=forloop.counter0 catagoryCount=forloop.parentloop.counter0 %}
                {% elif ItemForm.layout.value == 'choice' %}
                  {% include 'getdata/choiceBudgetLayout.html' with form=ItemForm itemCount=forloop.counter0 catagoryCount=forloop.parentloop.counter0 %}
                {% endif %}
            {% endif %}
          {% endfor %}
        <tr class="txt_center Row_{{ CatForm.enName.value}}" style="line-height:4em; background:Silver;">
          <td>
            <a onclick="ToggleDisable('{{ CatForm.enName.value}}')">
              {{ CatForm.name.value }}
              <span style="float:left;">
                <i class="fa fa-caret-down {{ CatForm.enName.value}}" style="font-size:30px; padding:7px;"></i>
                <i class="fa fa-caret-up {{ CatForm.enName.value}}" style="font-size:30px; padding:7px;" hidden></i>
              </span>
            <!--/a-->
          </td>
          <td>{{ CatForm.catagory_cost }}</td>
          <td>TBD</td>
          <td>{{ CatForm.detail.value }}</td>
          <td></td>
        </tr>
        </tbody>
      {% endfor %}
    </table>
    <br />
    <br />
    <br />
    <button type="submit" >Submit</button>    <br />
    <br />

  </form>
</div>




{% endblock %}

Thx

like image 878
Bigga Avatar asked Feb 28 '18 09:02

Bigga


People also ask

How to validate fields in Django?

Django provides built-in methods to validate form data automatically. Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class.

What is formset in Django?

A formset is a layer of abstraction to work with multiple forms on the same page. It can be best compared to a data grid. Let's say you have the following form: >>> from django import forms >>> class ArticleForm(forms.

What does clean do Django?

The clean() method on a Field subclass is responsible for running to_python() , validate() , and run_validators() in the correct order and propagating their errors. If, at any time, any of the methods raise ValidationError , the validation stops and that error is raised.


2 Answers

ModelFormsets require form.id. It is rendered as a hidden field. You will need to implement it with both formsets.

{% for form in formset %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}
    <!-- form.visible fields go here -->
{% endfor %}
like image 91
Carl Brubaker Avatar answered Oct 01 '22 05:10

Carl Brubaker


As an addendum to @unixo 's answer, simply putting:

{{ form.id }}

without any surrounding HTML tags, will be converted to the following when the template is rendered (values for name, value and id will be generated by your formset_factory):

<input type="hidden" name="form-1-id" value="2" id="id_form-1-id">

Just make sure it's indented into the for form in formset loop.

Meaning you don't need to add class="hidden" unless you have some particular handling of hidden fields you want.

like image 30
J-a-n-u-s Avatar answered Oct 01 '22 05:10

J-a-n-u-s