Comme le titre le demande, pourquoi les gars de Django ont-ils décidé d'implémenter l'objet request.POST avec un querydict (qui, bien sûr, à son tour, rend le tout immuable?)
Je sais que vous pouvez le modifier en faisant une copie des données de publication
post = request.POST.copy()
mais pourquoi faire ça? Ce serait sûrement plus simple de permettre à la chose d'être mutable de toute façon? Ou est-il également utilisé pour une autre raison qui pourrait causer des problèmes?
request.POST
a été soumise avec plus de données qu'elle ne l'a été en réalité.Réponses:
C'est un peu un mystère, n'est-ce pas? Plusieurs théories superficiellement plausibles se révèlent erronées lors de l'enquête:
Pour que l'
POST
objet n'ait pas à implémenter de méthodes de mutation? Non: l'POST
objet appartient à ladjango.http.QueryDict
classe , qui met en œuvre un ensemble complet de méthodes de mutation , y compris__setitem__
,__delitem__
,pop
etclear
. Il implémente l'immuabilité en vérifiant un indicateur lorsque vous appelez l'une des méthodes de mutation. Et lorsque vous appelez lacopy
méthode, vous obtenez une autreQueryDict
instance avec l'indicateur mutable activé.Pour une amélioration des performances? Non: la
QueryDict
classe ne bénéficie d'aucun avantage en termes de performances lorsque l'indicateur mutable est désactivé.Pour que l'
POST
objet puisse être utilisé comme clé de dictionnaire? Non: lesQueryDict
objets ne sont pas hachables.Pour que les
POST
données puissent être construites paresseusement (sans s'engager à lire toute la réponse), comme revendiqué ici ? Je ne vois aucune preuve de cela dans le code: pour autant que je sache, l'ensemble de la réponse est toujours lu, soit directement , soit viaMultiPartParser
pour lesmultipart
réponses.Pour vous protéger contre les erreurs de programmation? J'ai vu cela revendiqué, mais je n'ai jamais vu une bonne explication de ce que sont ces erreurs et comment l'immuabilité vous protège contre elles.
Dans tous les cas,
POST
n'est pas toujours immuable : lorsque la réponse estmultipart
, alorsPOST
est mutable. Cela semble mettre le kibosh sur la plupart des théories auxquelles vous pourriez penser. (À moins que ce comportement ne soit un oubli.)En résumé, je ne vois aucune justification claire dans Django pour que l'
POST
objet soit immuable pour les non-multipart
requêtes.la source
Si la demande était le résultat d'une
form
soumission Django , alors il est raisonnable que POSTimmutable
s'assure de l'intégrité des données entre la soumission du formulaire et la validation du formulaire . Cependant, si la demande n'a pas été envoyée via uneform
soumission Django , alors POST estmutable
comme il n'y a pas de validation de formulaire.Vous pouvez toujours faire quelque chose comme ceci: (selon le commentaire de @ leo-the-manic )
la source
Mise à jour :
Gareth Rees avait raison de dire que les points 1 et 3 n'étaient pas valables dans ce cas. Bien que je pense que les points 2 et 4 sont toujours valables, je vais donc laisser les thèses ici.
(J'ai remarqué que l'
request.POST
objet à la fois de Pyramid (Pylon) et de Django est une forme deMultiDict
. Donc, c'est peut-être une pratique plus courante que de rendrerequest.POST
immuable.)Je ne peux pas parler pour les gars de Django, bien qu'il me semble que cela pourrait pour certaines de ces raisons:
La performance . les objets immuables sont «plus rapides» que les objets mutables en ce sens qu'ils permettent des optimisations substantielles. Un objet est immuable signifie que nous pouvons lui allouer de l'espace au moment de sa création , et les besoins en espace ne changent pas. Il a également des choses comme l'efficacité de copie et l'efficacité de comparaison à cause de cela.Edit : ce n'est pas le casQueryDict
comme l'a souligné Gareth Rees.request.POST
, il semble qu'aucune activité côté serveur ne doive modifier les données de la demande . Et par conséquent, les objets immuables sont plus adaptés, sans oublier qu'ils ont un avantage substantiel en termes de performances.Les objets immuables peuvent être utilisés commeEdit : mon erreur, immuable n'implique pas directement hashable ; Cependant, les objets hachables sont généralement également immuables .dict
clés, ce qui, je suppose, pourrait être très utile quelque part dans Django.request.POST
(en particulier à des plugins tiers et à l'extérieur), vous pouvez vous attendre à ce que cet objet de requête de l'utilisateur reste inchangé.D'une certaine manière, ces raisons sont également des réponses génériques à "immuable vs mutable?" question. Je suis certain qu'il y a beaucoup plus de considérations de conception que ci-dessus dans le cas de Django.
la source
sessions
un moyen rapide d'obtenir et de modifier des données entre les états.POST
s'agit d'unQueryDict
objet et ces objets n'obtiennent aucun avantage en termes de performances en étant immuables. Et votre point (3) ne peut pas être la réponse, car lesQueryDict
objets ne sont pas hachables et ne peuvent donc pas être utilisés comme clés de dictionnaire.QueryDict
avant de répondre.requests.POST._mutable = True; requests.POST['foo'] = 'bar'; request.POST._mutable = False
J'aime qu'il soit immuable par défaut. Comme indiqué, vous pouvez le rendre mutable si vous en avez besoin, mais vous devez être explicite à ce sujet. C'est comme "Je sais que je peux faire de mon débogage de formulaire un cauchemar mais je sais ce que je fais maintenant."
la source
J'ai trouvé cela dans un commentaire sur Stack Answer https://stackoverflow.com/a/2339963
la source
Remarque: les
multipart
requêtes sont immuables depuis Django 1.11 https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292Ils étaient mutables dans les versions précédentes.
la source