Opened 7 years ago

Closed 7 years ago

#27989 closed Bug (fixed)

Passing an empty QueryDict to a form stores it as a plain dictionary

Reported by: Stefan Wehrmeyer Owned by: Abhishek Gautam
Component: Forms Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Passing an empty request.POST or request.FILES into a form, evaluates the arguments to False in these lines and stores a normal Python dictionary instead.

self.data = data or {}
self.files = files or {}

This breaks the assumption that what you pass into the form will be kept allowing access to special methods like QueryDict.getlist.

The following code accepts zero or more uploaded files, but breaks when no files are uploaded because the passed QueryDict gets discarded and a dict has no method getlist.

class UploadForm(forms.Form):
    documents = forms.FileField(
        required=False,
        widget=forms.FileInput(attrs={
          'multiple': True
        })
    )

    def save(self):
        for doc in self.files.getlist('documents'):
            handle_doc(doc)


form = UploadForm(request.POST, request.FILES)
form.save()

# When request.FILES is empty
# AttributeError: 'dict' object has no attribute 'getlist'

Instead of

self.data = data or {}
self.files = files or {}

it should be something like

self.data = QueryDict() if data is None else data
self.files = QueryDict() if files is None else files

which would keep whatever was passed except None and fall back to an empty QueryDict instance which is the type of the usual parameter.

The only backwards incompatible change here would be that self.data and self.files are no longer mutable as they would be when set to empty dicts, but afaik the attributes are not changed anyway.

Change History (5)

comment:1 by Stefan Wehrmeyer, 7 years ago

comment:2 by Stefan Wehrmeyer, 7 years ago

Has patch: set

comment:3 by Tim Graham, 7 years ago

Triage Stage: UnreviewedAccepted

comment:4 by Abhishek Gautam, 7 years ago

Owner: changed from nobody to Abhishek Gautam
Status: newassigned

I am working on this.

comment:5 by Tim Graham <timograham@…>, 7 years ago

Resolution: fixed
Status: assignedclosed

In 1aa8e860:

Fixed #27989 -- Preserved empty QueryDicts for form's data/files args.

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