As the title asks, why did the Django guys decide to implement the request.POST object with a querydict (which, of course, in turn, makes the whole thing immutable?)
I know you can mutify it by making a copy of the post data
post = request.POST.copy()
but why do this? Surely it would be simpler just to allow the thing to be mutable anyway? Or is it being used for some other reason too which might cause issue?
Django puts data in request. POST when a user submits a form with the attribute method="post" . Line 10: You retrieve the submitted value by accessing the data at the key "follow" , which you defined in your template with the name HTML attribute on your <button> elements.
In an HttpRequest object, the GET and POST attributes are instances of django.http.QueryDict , a dictionary-like class customized to deal with multiple values for the same key. This is necessary because some HTML form elements, notably <select multiple> , pass multiple values for the same key.
django - This QueryDict instance is immutable - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.
Django uses request and response objects to pass state through the system. When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function.
It's a bit of a mystery, isn't it? Several superficially plausible theories turn out to be wrong on investigation:
So that the POST
object doesn't have to implement mutation methods? No: the POST
object belongs to the django.http.QueryDict
class, which implements a full set of mutation methods including __setitem__
, __delitem__
, pop
and clear
. It implements immutability by checking a flag when you call one of the mutation methods. And when you call the copy
method you get another QueryDict
instance with the mutable flag turned on.
For performance improvement? No: the QueryDict
class gains no performance benefit when the mutable flag is turned off.
So that the POST
object can be used as a dictionary key? No: QueryDict
objects are not hashable.
So that the POST
data can be built lazily (without committing to read the whole response), as claimed here? I see no evidence of this in the code: as far as I can tell, the whole of the response is always read, either directly, or via MultiPartParser
for multipart
responses.
To protect you against programming errors? I've seen this claimed, but I've never seen a good explanation of what these errors are, and how immutability protects you against them.
In any case, POST
is not always immutable: when the response is multipart
, then POST
is mutable. This seems to put the kibosh on most theories you might think of. (Unless this behaviour is an oversight.)
In summary, I can see no clear rationale in Django for the POST
object to be immutable for non-multipart
requests.
If the request was the result of a Django form
submission, then it is reasonable for POST being immutable
to ensure the integrity of the data between the form submission and the form validation. However, if the request was not sent via a Django form
submission, then POST is mutable
as there is no form validation.
You can always do something like this: (as per @leo-the-manic's comment)
# ..... mutable = request.POST._mutable request.POST._mutable = True request.POST['some_data'] = 'test data' request.POST._mutable = mutable # ......
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With