django-为什么request.POST对象是不可变的?
正如标题所问,为什么Django人决定用querydict实现request.POST对象(当然,这反过来又使整个事情不可变?) 我知道你可以通过复制一份post数据来破坏它django-为什么request.POST对象是不可变的?,django,post,Django,Post,正如标题所问,为什么Django人决定用querydict实现request.POST对象(当然,这反过来又使整个事情不可变?) 我知道你可以通过复制一份post数据来破坏它 post = request.POST.copy() 但为什么要这样做呢?不管怎样,允许事物是可变的肯定会更简单?或者它也被用于其他可能导致问题的原因?更新: Gareth Rees认为第1点和第3点在本案中无效是正确的。虽然我认为第2点和第4点仍然有效,因此我将把论文留在这里 (我注意到Pyramid(Pylon)和D
post = request.POST.copy()
但为什么要这样做呢?不管怎样,允许事物是可变的肯定会更简单?或者它也被用于其他可能导致问题的原因?更新: Gareth Rees认为第1点和第3点在本案中无效是正确的。虽然我认为第2点和第4点仍然有效,因此我将把论文留在这里 (我注意到Pyramid(Pylon)和Django的
request.POST
对象都是某种形式的MultiDict
。因此,这可能比使request.POST
不可变更常见。)
我不能代表Django的人说话,尽管在我看来可能是因为以下原因:
QueryDict
的情况并非如此李>
request.POST
的情况下,似乎服务器端的任何活动都不需要更改请求的数据。因此,不可变对象更适合,更不用说它们具有显著的性能优势dict
键,我想这在Django的某些地方可能非常有用。。
编辑:我的错误,不可变并不直接意味着可散列;然而,散列对象通常也是不可变的李>
request.POST
(尤其是传递给第三方插件和out)时,您可以预期来自用户的此请求对象将保持不变在某种程度上,这些原因也是对“不变与可变”问题的一般回答。我敢肯定,在Django的案例中,有比上述更多的设计考虑。这有点神秘,不是吗?一些表面上看似合理的理论在调查中被证明是错误的:
POST
对象就不必实现变异方法了?否:POST
对象属于,它实现了一整套变异方法,包括\uuuuu setitem\uuuuuuuu
、\uuuuuu delitem\uuuuu
、pop
和清除
。它通过在调用其中一个变异方法时检查标志来实现不变性。当您调用copy
方法时,您会得到另一个QueryDict
实例,并且启用了可变标志QueryDict
类在禁用可变标志时不会获得性能优势POST
对象可以用作字典键?否:QueryDict
对象不可散列POST
数据(无需提交读取整个响应)?我在代码中看不到这方面的证据:据我所知,整个响应都是读取的,或者是通过多部分
响应读取的POST
并不总是不变的:当响应是multipart
时,POST
是可变的。这似乎使你可能想到的大多数理论都大错特错。(除非这种行为是疏忽。)
总之,我在Django中看不到
POST
对象对于非多部分
请求不可变的明确理由。如果请求是Django表单提交的结果,然后,POST是不可变的,以确保提交表单和验证表单之间数据的完整性。但是,如果请求不是通过Django表单提交的,则POST是可更改的,因为没有表单验证
你总是可以这样做的:(根据)
我在Stack Answer的评论中发现了这一点
而且它必须是不可变的,这样才能懒散地构建它。复制强制获取所有POST数据。在复制之前,可能无法获取所有副本。此外,对于多线程WSGI服务器来说,如果它是不可变的,那么它将非常有用
我喜欢它在默认情况下是不可变的。
如前所述,如果需要,您可以使其可变,但必须明确说明。
这就像“我知道我可以让表单调试成为一场噩梦,但我知道我现在在做什么。”请注意:多部分请求自Django 1.11以来是不可变的
在以前的版本中,它们是可变的。为什么您希望它是可变的?您可以从中获取数据,并在视图中使用/修改它。通过向其中添加数据,您可能会给人一种印象,即request.POST
提交的数据比实际提交的数据多。我并不希望它是可变的。不超过,比方说,我想要冰激凌变凉。但就冰淇淋而言,如果它不冷,它就会融化,然后你会因为弄得一团糟而被责骂。但是对于request.POST对象。。。我的意思是,如果我要把我的代码搞砸,我会把它搞砸的。我不知道开发人员向POST对象添加数据并导致问题的流行
# .....
mutable = request.POST._mutable
request.POST._mutable = True
request.POST['some_data'] = 'test data'
request.POST._mutable = mutable
# ......