# POST data yielding hidden form missing error

**URL:** <https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720>\
**Category:** Mystery Errors\
**Created:** [October 16, 2024, 8:15pm UTC](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720 "2024-10-16T20:15:38Z")\
**Posts on this page:** 5\
**Page:** 2

<div class="post-metadata">

**Author:** ![jlc1978](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/jlc1978/32/23432_2.png) [@jlc1978](https://forum.djangoproject.com/u/jlc1978)\
**Post date:** [October 21, 2024, 11:03am UTC](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720/22 "2024-10-21T11:03:20Z")

</div>

> [@KenWhitesell](#):
>
> Regarding `extra`, default is 1 per [Formsets | Django documentation | Django](https://docs.djangoproject.com/en/5.1/topics/forms/formsets/#formsets)

Thanks. I’ve gotten used to the first being 0 in python that I default to that.

I removed objective from the formset:

`ObjectiveTextFormSet = modelformset_factory(ObjectiveText, fields = ["objective_text"], extra = 0, widgets={'objective_text': Textarea(attrs={'cols': 15, 'rows': 5})} )`

I’ve tried to get error messages but am not sure if I am or not. The terminal, in response to my code, yields:

```auto
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

[21/Oct/2024 10:55:13] "GET /ISO22301/home/ HTTP/1.1" 200 15718
[21/Oct/2024 10:55:13] "GET /static/css/styles.css HTTP/1.1" 304 0
Formset errors: []
Not Vald
{'formset_list': <ObjectiveTextFormFormSet: bound=True valid=False total_forms=0>}
[21/Oct/2024 10:55:19] "POST /ISO22301/data/ HTTP/1.1" 200 638
[21/Oct/2024 10:55:19] "GET /static/css/styles.css HTTP/1.1" 304 0

```

So it looks like it is using GET to render the initial template, and after I enter data using POST to get the view. I split the home view into one that renders the template as a blank and then a separate view, data, to handle the POST data, just in case having them in the same view was causing the issue by creating a fresh, blank formset when called by POST.

Looking at the print data, the error message is a blank dictionary, but it is not executing the

```auto
    if request.method == "POST":

```

loop.  
views (probably don’t need the duplicate **formset\_list = ObjectiveTextFormSet(request.POST):**

```auto
def home(request):
    
    # Create unique prefixes for each element
                
        formset_list = [ 
            ObjectiveTextFormSet
                        (prefix=f'row-{i}',
                        queryset=ObjectiveText.objects.filter(
                            objective__objective_row=i
                            ).order_by('objective__objective_num')
                            )
            for i in range(1,7)       
        ]

        objheader = [1,2,3,4,5,6,7,8]

        # Add the formset to context dictionary
        context = {
            'formset_list': formset_list,
            'objheader': objheader,
        }
    
        return render(request, "ISO22301/home.html", context)

def data(request):
    context={}
    formset_list = ObjectiveTextFormSet(request.POST)
    context['formset_list']=formset_list
    print("Formset errors:",formset_list.errors)
    if request.method == "POST":
        formset_list = ObjectiveTextFormSet(request.POST)
    for formset in formset_list:
        if formset.is_valid():
            print("Valid")
            formset.save()
            return render(request, 'ISO22301/generic.html', context)
        else:
            print("Formset errors after checkink if valid:",formset_list.errors)
            return render(request, 'ISO22301/generic.html', context)
    print("Not Vald")
    print(context)
    return render(request, 'ISO22301/home.html', context)

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [October 21, 2024, 11:15am UTC](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720/23 "2024-10-21T11:15:07Z")

</div>

> [@jlc1978](#):
>
> I split the home view into one that renders the template as a blank and then a separate view, data, to handle the POST data, just in case having them in the same view was causing the issue

This is exactly the opposite of the common / “default” Django pattern, which is one view to handle both the get and post, where the difference between the two is handled by an `if request.method == 'POST'` condition.

> [@jlc1978](#):
>
> ` formset_list = ObjectiveTextFormSet(request.POST)`

When you bind the submitted data, it needs to be bound to the **same** formset(s) structures that were created in for the get. That means you need to create the same list using the same parameters (queryset and prefix) in both cases. (This is one of the reasons why the common pattern is to handle both get and post in the same view - you can share the same code for building the forms.)

> [@jlc1978](#):
>
> I’ve gotten used to the first being 0 in python that I default to that.

Yea, but this is a different situation. When you’re creating a formset, you’ve got some forms being created with existing data, identified by the queryset. You also have the ability to define _additional_ forms for adding _new_ data - and that’s the purpose of the `extra` attribute. In your case here, you’ve got exactly the right number of objects created, and so don’t need any additional forms to create new objects.

---

<div class="post-metadata">

**Author:** ![jlc1978](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/jlc1978/32/23432_2.png) [@jlc1978](https://forum.djangoproject.com/u/jlc1978)\
**Post date:** [October 21, 2024, 12:05pm UTC](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720/24 "2024-10-21T12:05:12Z")

</div>

I fixed the view to handle GET and POST. My engineering background makes me want to split problems into smaller parts.

Thanks to your help, I got it working, although I am not sure exactly what is happening.

My error message was:

```auto
Errors: [{'id': ['This field is required.']}, 

```

repeated for each form.

It appears the id of each objective\_text as a hidden field Is required, so when I changed the template to include:

```auto
 {% for form in formset %}
    <td> {{ form.objective_text }} {{ form.objective.as_hidden }} {{ form.id.as_hidden }}</td>
 {% endfor %}

```

the form were Valid and it saved the data to the db.

It does overwrite the previous data, so for historical purposes I probably need to append the data to the db table or first copy and append the old data to another table.

views.py

```auto
def home(request):
    
    # Create unique prefixes for each element
                
        formset_list = [ 
            ObjectiveTextFormSet
                        (prefix=f'row-{i}',
                        queryset=ObjectiveText.objects.filter(
                            objective__objective_row=i
                            ).order_by('objective__objective_num')
                            )
            for i in range(1,7)       
        ]

        objheader = [1,2,3,4,5,6,7,8]

        # Add the formset to context dictionary
        context = {
            'formset_list': formset_list,
            'objheader': objheader,
        }
        if request.method == "POST":
            formset_list=[ObjectiveTextFormSet(request.POST, prefix=f'row-{i}',
                        queryset=ObjectiveText.objects.filter(
                            objective__objective_row=i
                            ).order_by('objective__objective_num')
                            )
            for i in range(1,7)]
            print(formset_list)
            for formset in formset_list:
                if formset.is_valid():
                    print('Valid')
                    formset.save()
                else:
                    for formset in formset_list:
                        print('Errors: ', formset.errors)    
            return render(request, 'ISO22301/home.html', context)
        else:
            for formset in formset_list:
                print('Errors: ', formset.errors)
            return render(request, "ISO22301/home.html", context)

```

Side note:  
I am next going to include the all the entries in the database \to show what has already been entered so someone can save data and then continue to update the data with currently entered values shown. I suspect a variable in the formset\_list= that iterates over the data is the approach?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [October 21, 2024, 12:19pm UTC](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720/25 "2024-10-21T12:19:09Z")

</div>

> [@jlc1978](#):
>
> I am next going to include the all the entries in the database \to show what has already been entered so someone can save data and then continue to update the data with currently entered values shown.

I’m not following what you’re looking to do here.

When you bring up the form, you should see what’s currently in the models. Beyond that, I don’t think I’m “getting” what you’re trying to describe.

---

<div class="post-metadata">

**Author:** ![jlc1978](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/jlc1978/32/23432_2.png) [@jlc1978](https://forum.djangoproject.com/u/jlc1978)\
**Post date:** [October 21, 2024, 12:42pm UTC](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720/26 "2024-10-21T12:42:37Z")

</div>

Sorry I wasn’t clear.

The data entry template, “home” shows all the current values for objective\_test, as desired.

Those entries will be used to populate a different template, that displays everything in nice color coded graphics.

At some point, users will want to be able to roll back an entry or see what the historical text was so I’d like to save it somewhere to be able to recall it if desired. Right now, because the way the db is setup, a new entry overwrites the old, which is fine since I use the table for displaying the current entries.

[Previous page](https://forum.djangoproject.com/t/post-data-yielding-hidden-form-missing-error/35720.md?page=1)
