Opened 11 years ago
Closed 11 years ago
#22678 closed Bug (wontfix)
forms.Form silently won't bind to POST data (under certain combinations of key and label)
Reported by: | brycenesbitt | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 1.5 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
In this example:
class TestFormX(forms.Form): test_one = forms.CharField(required=True) def __init__(self, *args, **kwargs): super(TestFormX, self).__init__(*args, **kwargs) self.fields['test_two'] = forms.IntegerField(required=False) for key in (3,4): self.fields[key] = forms.IntegerField(required=False, label='must have a label') def sandbox2(request): if request.method == 'POST': form = TestFormX(request.POST) if form.is_valid(): print 'Form is valid' else: print form.errors else: form = TestFormX() return render(request, 'xxx_sandbox2.html', {'form' : form}, status=200)
Form fields test_one and test_two act normally. Fields 3 and 4 render and appear to work, but
won't bind data from the request.POST. Thus, any input by the user is lost.
This was found on a dynamically built from.Form, where an integer database primary key was used as the field name.
Change History (3)
comment:1 by , 11 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 11 years ago
Resolution: | invalid |
---|---|
Status: | closed → new |
I intended to convey that above: the issue is the integer key. Strings work, integers don't.
The form as built 'looked' reasonable, but had a murky and hard to track problem.
Most code paths blow up on integers, but not this one.
The proposed fix is to assert on string for the key.... or almost as good perform the string
concatenation (e.g. 'id_'+key) in all cases, so it blows up nice and fast with any form of key that
does not actually fully work.
This kind of does it, subject to a future optimizer dropping the empty string:
# django/forms/forms.py class BaseForm(object): for name, field in self.fields.items(): html_class_attr = '' bf = self[name+'']
comment:3 by , 11 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I think it's reasonable to expect that most people won't mix types in the fields
dictionary. I'm sorry you ran into the issue, but I don't think fixing it is worthwhile.
Hi,
I believe the problem here is that you're using integers as keys on
TestFormX.fields
which is not supported (only strings are allowed).Things should work if you use
for key in ('3', '4'):
.Marking this as
invalid
consequently.Thanks.