Forms: multiple text input with same names

Hello hello,

Imagine a form like this:

<form action="{% url 'somewhere' %}" method="post">
<ul>
    <li>
        <label for="mytext0"></label>
        <input type="text" value="" name="mytext" id="mytext0">
        <button type="button">Add a new text</button>
    </li>
</ul>
</form>

When the user clicks the button Add a new text, some javascript dynamically populate the form so it becomes:

<form action="{% url 'somewhere' %}" method="post">
<ul>
    <li>
        <label for="mytext0">My text</label>
        <input type="text" value="" name="mytext" id="mytext0">
        <button type="button">Add a new text</button>
    </li>
    <li>
        <label for="mytext1">My text</label>
        <input type="text" value="" name="mytext" id="mytext1">
        <button type="button">Add a new text</button>
    </li>
</ul>
</form>

… and so on.

Notice the text inputs have the same name attribute.

In GET method, this would work and result in a query string similar to ?mytext=foo&mytext=bar.

In POST method, this would result in something like:

-----------------------------44380802120381848453673825967
Content-Disposition: form-data; name="mytext"

bar
-----------------------------44380802120381848453673825967
Content-Disposition: form-data; name="mytext"

foo
-----------------------------44380802120381848453673825967--

Now how to handle this dynamically in django? [As far as I know, cleaned_data does not support getlist() for CharField? (please tell me I’m wrong!) ]

  • In the clean() method of the form
  • in the form_valid method of the view

Thanks!

That is correct - however, you can retrieve the values from request.POST.getlist()

mm thanks Ken.

But then does that mean it suddenly becomes impossible (?) to leverage the form.Fields in the form declaration for individual “instances” of these inputs?

What “leverage” are you talking about here?

What you’re creating isn’t a CharField, it’s actually closer to a SplitArrayField. (Perhaps not exactly, but as an idea to build from.)

What isn’t clear yet is what you’re going to do with this data after it has been submitted - that may provide more clarity.

nothing fancy, the end result is n rows, one for each text input that was POSTed (I am simplifying but that’s the base mechanism).

Wondering if I could do smth along the lines of:

theform(forms.Form):
   text = formsCharField(...)

   def clean(self):
       texts = self.data.getlist('text', [])
       for txt in texts:
           pass
           # validate using the CharField above
           # if valid, add to cleaned_data
       
        return cleaned_data # to be used in the view

Actually, if you’re talking about creating multiple instances of a model from these, you’d be better served using a formset. That’s why they exist.