Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - why is the request.POST object immutable?

Tags:

post

django

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?

like image 331
bharal Avatar asked Sep 26 '12 22:09

bharal


People also ask

What does request Post do in Django?

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.

What are request get and request post objects in Django?

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.

Is Django Queryset immutable?

django - This QueryDict instance is immutable - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.

What is request object in Django?

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.


2 Answers

It's a bit of a mystery, isn't it? Several superficially plausible theories turn out to be wrong on investigation:

  1. 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.

  2. For performance improvement? No: the QueryDict class gains no performance benefit when the mutable flag is turned off.

  3. So that the POST object can be used as a dictionary key? No: QueryDict objects are not hashable.

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

  5. 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.

like image 150
Gareth Rees Avatar answered Sep 17 '22 23:09

Gareth Rees


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 # ...... 
like image 44
un33k Avatar answered Sep 21 '22 23:09

un33k