# Error when creating formset from POST data in test

**URL:** <https://forum.djangoproject.com/t/error-when-creating-formset-from-post-data-in-test/27029>\
**Category:** Mystery Errors\
**Created:** [January 17, 2024, 8:38am UTC](https://forum.djangoproject.com/t/error-when-creating-formset-from-post-data-in-test/27029 "2024-01-17T08:38:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Encephala](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/encephala/32/18460_2.png) [@Encephala](https://forum.djangoproject.com/u/Encephala)\
**Post date:** [January 17, 2024, 8:38am UTC](https://forum.djangoproject.com/t/error-when-creating-formset-from-post-data-in-test/27029/1 "2024-01-17T08:38:19Z")

</div>

Context: I’m building a basic bookkeeping application, just updated to Django 5.0.1.

I have a complicated custom `CreateView` which render a form for an `Entry` as well as the rows in that entry, `EntryRow`s. The `post` method of this view has the following code snippet:

```
    entryform = EntryForm(request.POST)
    entryrow_formset = EntryRowFormSet(request.POST)

    if entryform.is_valid() and entryrow_formset.is_valid():
        entry = entryform.save()

        entryrow_instances = entryrow_formset.save(commit = False)

```

This works perfectly!

I built a test for this view. I used the view to trigger this `post` method, logged the `request.POST` and copied the whole thing to be hardcoded in my test. However, the following snippet

```
    data = {
        'journal': ['journ1'], 'notes': [''], 'form-TOTAL_FORMS': ['2'],
        'form-INITIAL_FORMS': ['0'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'],
        'form-0-id': [''], 'form-0-date': ['2023-12-27'], 'initial-form-0-date': ['2023-12-27', '', ''],
        'form-0-ledger': ['test1'], 'form-0-account': ['acc1'], 'form-0-value': ['2'], 'form-1-id': [''],
        'form-1-DELETE': [''], 'form-1-date': ['2023-12-27'], 'form-1-ledger': ['test2'],
        'form-1-account': ['acc2'], 'form-1-value': ['-3']
    }

    formset = EntryRowFormSet(data)
    print(formset.is_valid())

    print(formset.non_form_errors())

```

Bafflingly, this formset always yields the error: `ManagementForm data is missing or has been tampered with. Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS, form-MIN_NUM_FORMS, form-MAX_NUM_FORMS. You may need to file a bug report if the issue persists.`

Those fields are clearly in the `data` right? Is this a bug in Django?

For reference, here is the code for the `EntryRowForm` and the `EntryRowBaseFormSet`:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/f/4/f4233ae42a8dabae53be85634fa6f2c9237713a1.png)

The `EntryRowFormSet` is constructed using the `modelformset_factory` with default settings.

Thanks in advance for any help!

---

<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:** [January 17, 2024, 12:12pm UTC](https://forum.djangoproject.com/t/error-when-creating-formset-from-post-data-in-test/27029/2 "2024-01-17T12:12:56Z")

</div>

I don’t believe those values are submitted as lists. (You can’t trust that a `print` function is going to give you an accurate representation of the internal structure of an object.)

If you’re supplying form data for a form, you supply it as “key: value”, not “key: [value]”. See the examples at [The Forms API](https://docs.djangoproject.com/en/5.0/ref/forms/api/#module-django.forms).  
(Yes, it’s possible that it works for some other values in forms, but it doesn’t appear to work in the management form.)

---

<div class="post-metadata">

**Author:** ![Encephala](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/encephala/32/18460_2.png) [@Encephala](https://forum.djangoproject.com/u/Encephala)\
**Post date:** [January 17, 2024, 7:17pm UTC](https://forum.djangoproject.com/t/error-when-creating-formset-from-post-data-in-test/27029/3 "2024-01-17T19:17:35Z")

</div>

Thanks for the quick reply!

You were spot on; even though the `request.POST` got printed as the snippet below, the actual data should have just been passed as strings, not lists of strings.

```auto
<QueryDict: {'journal': ['journ1'], 'notes': [''], 'form-TOTAL_FORMS': ['2'], 'form-INITIAL_FORMS': ['0'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'], 'form-0-id': [''], 'form-0-date': ['2023-12-27'], 'initial-form-0-date': ['2023-12-27'], 'form-0-ledger': ['test1'], 'form-0-account': ['acc1'], 'form-0-value': ['2'], 'form-1-id': [''], 'form-1-DELETE': [''], 'form-1-date': ['2023-12-27'], 'form-1-ledger': ['test2'], 'form-1-account': ['acc2'], 'form-1-value': ['-3']}>

```

Also for completeness, here’s what `data` should look like:

```auto
data = {
    'journal': 'journ1', 'notes': '', 'form-TOTAL_FORMS': '2',
    'form-INITIAL_FORMS': '0', 'form-MIN_NUM_FORMS': '0', 'form-MAX_NUM_FORMS': '1000',
    'form-0-id': '', 'form-0-date': '2023-12-27', 'initial-form-0-date': '2023-12-27',
    'form-0-ledger': 'test1', 'form-0-account': 'acc1', 'form-0-value': '2', 'form-1-id': '',
    'form-1-DELETE': '', 'form-1-date': '2023-12-27', 'form-1-ledger': 'test2',
    'form-1-account': 'acc2', 'form-1-value': '-3'
}

```

Note that the key `initial-form-0-date` had two empty strings in its value “list”, I removed those as well.

---

<div class="post-metadata">

**Author:** ![Encephala](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/encephala/32/18460_2.png) [@Encephala](https://forum.djangoproject.com/u/Encephala)\
**Post date:** [January 17, 2024, 7:23pm UTC](https://forum.djangoproject.com/t/error-when-creating-formset-from-post-data-in-test/27029/4 "2024-01-17T19:23:27Z")

</div>

For complete completeness, I also have the following test:

```python
def test_entries_create(self):
    data = {
        'journal': ['journ1'], 'notes': [''], 'form-TOTAL_FORMS': ['3'],
            'form-INITIAL_FORMS': ['0'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'],
            'form-0-id': [''], 'form-0-date': ['2023-12-27'], 'initial-form-0-date': ['2023-12-27', '', ''],
            'form-0-ledger': ['test1'], 'form-0-account': ['acc1'], 'form-0-value': ['69'], 'form-1-id': [''],
            'form-1-DELETE': [''], 'form-1-date': ['2023-12-27'], 'form-1-ledger': ['test2'],
            'form-1-account': ['acc2'], 'form-1-value': ['-60'], 'form-2-id': [''], 'form-2-DELETE': [''],
            'form-2-date': ['2023-12-27'], 'form-2-ledger': ['test2'], 'form-2-account': ['acc1'],
            'form-2-value': ['-9']
    }

    response = self.client.post(reverse("entries:create"), data)

    self.assertEqual(response.status_code, 302)
    self.assertEqual(Entry.objects.count(), 1)
    self.assertEqual(EntryRow.objects.count(), 3)

```

This passes just fine. The difference is that here, the dict is passed as data to the POST request, whereas in the test in my original post, the data got passed to the formset. The latter doesn’t enjoy the lists.
