#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 Changed 12 months ago by bmispelon

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

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.

comment:2 Changed 12 months ago by brycenesbitt

  • Resolution invalid deleted
  • Status changed from closed to 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.

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/forms.py
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 12 months ago by brycenesbitt (previous) (diff)

comment:3 Changed 11 months ago by timo

  • Resolution set to wontfix
  • Status changed from new to 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.

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