Opened 3 weeks ago

Last modified 2 weeks ago

#29459 new Cleanup/optimization

Make Form data/files initialize with an empty MultiValueDict rather than dict

Reported by: Sven R. Kunze Owned by: nobody
Component: Forms Version: 2.0
Severity: Normal Keywords: Form QueryDict
Cc: Herbert Fortes Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description

You might have a look here:

https://github.com/django/django/blob/362813d6287925b8f63f/django/forms/forms.py#L78

None is converted to a regular dict but not to a QueryDict.

Methods of the form might rely on the API of a QueryDict such as 'iterlists' or 'getlist' which a regular dict doesn't provide.

Change History (9)

comment:1 Changed 3 weeks ago by Herbert Fortes

Cc: Herbert Fortes added

Hi,

To be clear, QueryDict is a subclass of dict.

Is the idea to add a feature?

At a first look, the dictionary is there to avoid that the code breaks.
# edited to fix english

Regards,

Last edited 3 weeks ago by Herbert Fortes (previous) (diff)

comment:2 in reply to:  1 Changed 3 weeks ago by Sven R. Kunze

Replying to Herbert Fortes:

Is the idea to add a feature?

Sorry, if that wasn't clear from the issue itself. Instead of:

        self.data = {} if data is None else data

this would be 100% compatible with what views usually pass into forms:

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

At a first look, the dictionary is there to avoid that the code breaks.

I think so as well and it works in many places until people think they can rely on the QueryDict API such as 'iterlists' or 'getlist' which is not always true.

comment:3 Changed 3 weeks ago by Tim Graham

A similar issue was raised in #27989. The main concern I have is that this would couple django.forms to django.http.

comment:4 Changed 3 weeks ago by Sven R. Kunze

Yes, I thought that #27989 was the reason to change it from "data or {}" to ternary operator.

What do you think about:

1) either using MultiValueDict instead of QueryDict? That would couple django.forms to django.utils.datastructures

2) or moving QueryDict to django.utils.datastructures and then using it in the BaseForm constructor?

At least, MultiValueDict supports the getlist, setlist and lists APIs. So, those would behave the same because the dicts are empty anyway. Although, I would rather tend to option 2.

What do you think?

Last edited 3 weeks ago by Sven R. Kunze (previous) (diff)

comment:5 Changed 3 weeks ago by Simon Charette

I like the MultiValueDict approach, +1.

comment:6 Changed 3 weeks ago by Herbert Fortes

MultiValueDict +1

comment:7 Changed 2 weeks ago by Sven R. Kunze

Okay seems like we have winner. :D

Just exploring the other option a bit more: why is moving QueryDict to datastructures not a feasible option? It actually sounds like a more reasonable place for it.

comment:8 Changed 2 weeks ago by Tim Graham

Summary: data=None in Form results NOT in empty QueryDictMake Form data/files initialize with an empty MultiValueDict rather than dict
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

I agree that QueryDict should remain in django.http. I don't feel that it's something meant for use outside of the request/response cycle.

comment:9 Changed 2 weeks ago by Sven R. Kunze

I don't feel that it's something meant for use outside of the request/response cycle.

Sorry, for still nagging here, but I still don't understand why it cannot be moved to datastructures.

Its doc string: "A specialized MultiValueDict which represents a query string." <<< That sounds like a perfect valid datastructure handling encoding and query string syntax. Its source code has no reference to request/responses.


Also APIs MultiValueDict doesn't provide:

  • urlencode
  • encoding (getter and setter)
  • fromkeys
  • mutability
  • isinstance check


I just want to make sure we don't need to touch this part in 3 years AGAIN when somebody else needs the real thing.

Last edited 2 weeks ago by Sven R. Kunze (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top