Django - why is the request.POST object immutable?

As the title says, why did the Django guys decide to implement the request.POST object with the request (which, of course, makes everything the same?)

I know that you can ruin it by making a copy of the message data

post = request.POST.copy() 

but why do it? Of course, would it be easier to just let things be volatile anyway? Or is it being used for any other reason that might cause problems?

+72
post django
Sep 26 '12 at 10:21
source share
5 answers

It's a bit of a secret, isn't it? Several superficially plausible theories turn out to be erroneous in the investigation:

  • That the POST object should not implement mutation methods? No: the POST object belongs to the django.http.QueryDict class, which implements a complete set of mutation methods, including __setitem__ , __delitem__ , pop and clear . It implements immutability by checking the flag when you call one of the mutation methods. And when you call the copy method, you get another instance of QueryDict with the flag turned on.

  • To improve performance? No: The QueryDict class QueryDict not benefit from performance when disabling a mutable flag.

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

  • So, POST data can be created lazily (without reading the whole answer), as stated here ? I do not see any evidence of this in the code: as far as I can tell, the entire answer is always read, either directly or through MultiPartParser for multipart answers.

  • To protect you from programming errors? I saw how it was stated, but I never saw a good explanation of what these errors are, and how immutability protects you from them.

In any case, POST not always immutable: when the response is multipart , then POST is mutable. This seems to be a kibosh in most theories that you might think of. (If this behavior is not oversight.)

In conclusion, I do not see in Django a clear rationale for the POST object, which should be immutable for multipart requests.

+104
Sep 27
source share

If the request was the result of a Django form submission, then it is reasonable that the POST is immutable to ensure data integrity between the submission form and the validation form. However, if the request was not submitted via the Django form view, then POST is mutable , as there is no form validation.

You can always do something like this: (according to @ leo-the-manic comment )

 # ..... mutable = request.POST._mutable request.POST._mutable = True request.POST['some_data'] = 'test data' request.POST._mutable = mutable # ...... 
+56
Jan 21 '14 at 15:25
source share

Update

Gareth Rhys was right that points 1 and 3 were invalid in this case. Although I think that points 2 and 4 are still relevant, so I will leave theses here.

(I noticed that the request.POST object of both Pyramid (Pylon) and Django is some form of MultiDict . Therefore, perhaps this is a more common practice than making request.POST immutable.)




I can't speak for Django guys, although it seems to me that this may be due to some of these reasons:

  • Execution . immutable objects are β€œfaster” over mutable ones, since they allow for significant optimization. An immutable object means that we can allocate space for it during creation, and the requirements for space do not change. Because of this, it also has things like copy efficiency and comparison efficiency. QueryDict > Edit : This does not apply to QueryDict , as Gareth pointed out.
  • In the case of request.POST it seems that no activity on the server side will need to change the request data. And, therefore, immutable objects are more suitable, not to mention the fact that they have a significant advantage.
  • Immutable objects can be used as dict keys, which I suppose can be very useful somewhere in Django .. Edit : my error, immutable, does not directly imply hashing; Hashable objects are generally immutable.
  • When you go through request.POST (especially third-party plugins and exits), you can expect this request object from the user to remain unchanged.

To some extent, are these reasons also typical responses to "immutable vs mutable"? question. I am sure there are far more design considerations in Django than mentioned above.

+5
Sep 27
source share

I like that it is unchanged by default. As indicated, you can make it volatile if you need to, but you must be frank. It is like "I know I can make my form a nightmare debugging, but I know what I'm doing now."

+3
Mar 17 '15 at 15:24
source share

I found this in a comment on the stack answer https://stackoverflow.com/a/3/4128/

And it must be unchanged so that it can be built lazily. The copy forces to receive all POST data. While the copy cannot be selected. Also, for a multi-threaded WSGI server to work well enough, it is useful if it is unchanged

+2
Apr 30 '14 at 22:40
source share



All Articles