Opened 4 years ago

Closed 4 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


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'
            print form.errors
        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 Changed 4 years ago by Baptiste Mispelon

Resolution: invalid
Status: newclosed


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.


comment:2 Changed 4 years ago by brycenesbitt

Resolution: invalid
Status: closednew

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.

The proposed fix is to assert on string for the key.... or almost as good perform string concatenation 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/
class BaseForm(object):
 for name, field in self.fields.items():
     html_class_attr = ''
     bf = self[name+''] # Perform string operation to ensure the name key is a compatible type
Last edited 4 years ago by brycenesbitt (previous) (diff)

comment:3 Changed 4 years ago by Tim Graham

Resolution: wontfix
Status: newclosed

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.

Note: See TracTickets for help on using tickets.
Back to Top