Como pregunta el título, ¿por qué los chicos de Django decidieron implementar el objeto request.POST con un querydict (que, por supuesto, a su vez, hace que todo sea inmutable?)
Sé que puedes mutilarlo haciendo una copia de los datos de la publicación.
post = request.POST.copy()
pero ¿por qué hacer esto? Seguramente sería más simple permitir que la cosa fuera mutable de todos modos. ¿O también se está utilizando por alguna otra razón que podría causar problemas?
request.POST
se ha enviado con más datos de los que realmente ha sido.Respuestas:
Es un poco misterioso, ¿no? Varias teorías superficialmente plausibles resultan estar equivocadas en la investigación:
¿Para que el
POST
objeto no tenga que implementar métodos de mutación? No: laPOST
propiedad pertenece a ladjango.http.QueryDict
clase , que implementa un conjunto completo de procedimientos de mutación incluyendo__setitem__
,__delitem__
,pop
yclear
. Implementa la inmutabilidad marcando una bandera cuando llamas a uno de los métodos de mutación. Y cuando llamas alcopy
método, obtienes otraQueryDict
instancia con la bandera mutable activada.¿Para mejorar el rendimiento? No: la
QueryDict
clase no obtiene ningún beneficio de rendimiento cuando la bandera mutable está desactivada.¿Para que el
POST
objeto se pueda utilizar como clave de diccionario? No: losQueryDict
objetos no se pueden mezclar con hash.¿Para que los
POST
datos se puedan construir de forma perezosa (sin comprometerse a leer la respuesta completa), como se afirma aquí ? No veo evidencia de esto en el código: por lo que puedo decir, la totalidad de la respuesta siempre se lee, ya sea directamente o a travésMultiPartParser
de lasmultipart
respuestas.¿Para protegerte contra errores de programación? He visto este reclamo, pero nunca he visto una buena explicación de qué son estos errores y cómo la inmutabilidad te protege contra ellos.
En cualquier caso,
POST
es no siempre inmutable : cuando la respuesta esmultipart
, entoncesPOST
es mutable. Esto parece poner freno a la mayoría de las teorías que se te ocurran. (A menos que este comportamiento sea un descuido).En resumen, no veo una justificación clara en Django para que el
POST
objeto sea inmutable para las nomultipart
solicitudes.fuente
Si la solicitud fue el resultado de un
form
envío de Django , entonces es razonable que POSTimmutable
garantice la integridad de los datos entre el envío del formulario y la validación del formulario . Sin embargo, si la solicitud no se envió a través de unform
envío de Django , entonces POST esmutable
porque no hay validación del formulario.Siempre puedes hacer algo como esto: (según el comentario de @ leo-the-manic )
fuente
Actualización :
Gareth Rees tenía razón en que los puntos 1 y 3 no eran válidos en este caso. Aunque creo que los puntos 2 y 4 siguen siendo válidos, dejaré las tesis aquí.
(Me di cuenta de que el
request.POST
objeto tanto de Pyramid (Pylon) como de Django es una forma deMultiDict
. Así que quizás sea una práctica más común que hacerrequest.POST
inmutable).No puedo hablar por los chicos de Django, aunque me parece que podría hacerlo por algunas de estas razones:
Rendimiento . Los objetos inmutables son "más rápidos" que los mutables en el sentido de que permiten optimizaciones sustanciales. Un objeto es inmutable significa que podemos asignarle espacio en el momento de la creación y los requisitos de espacio no cambian. También tiene cosas como eficiencia de copia y eficiencia de comparación debido a eso.Editar : este no es el casoQueryDict
como señaló Gareth Rees.request.POST
, parece que ninguna actividad en el lado del servidor debería necesitar alterar los datos de la solicitud . Y, por lo tanto, los objetos inmutables son más adecuados, sin mencionar que tienen una ventaja de rendimiento sustancial.Los objetos inmutables se pueden usar comoEditar : mi error, inmutable no implica directamente hash ; Sin embargo, los objetos hash , normalmente también son inmutables .dict
claves, lo que supongo que podría ser muy útil en algún lugar de Django ..request.POST
(especialmente a complementos de terceros y hacia fuera), puede esperar que este objeto de solicitud del usuario permanezca sin cambios.De alguna manera, estas razones también son respuestas genéricas a "inmutable vs mutable?" pregunta. Estoy seguro de que hay muchas más consideraciones de diseño que las anteriores en el caso de Django.
fuente
sessions
forma breve de obtener y modificar datos entre estados.POST
es unQueryDict
objeto , y estos objetos no obtienen ningún beneficio de rendimiento por ser inmutables. Y su punto (3) no puede ser la respuesta, porque losQueryDict
objetos no se pueden usar con hash y, por lo tanto, no se pueden usar como claves de diccionario.QueryDict
antes de responder.requests.POST._mutable = True; requests.POST['foo'] = 'bar'; request.POST._mutable = False
Me gusta que sea inmutable por defecto. Como se señaló, puede hacerlo mutable si es necesario, pero debe ser explícito al respecto. Es como 'Sé que puedo hacer que la depuración de mi formulario sea una pesadilla, pero sé lo que estoy haciendo ahora'.
fuente
Encontré esto en un comentario en Stack Answer https://stackoverflow.com/a/2339963
fuente
Tenga en cuenta: la
multipart
solicitud es inmutable desde Django 1.11 https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292Eran mutables en versiones anteriores.
fuente