正如標題問,爲什麼Django的傢伙決定實施具有的QueryDict的request.POST對象(其中,當然,反過來又使一成不變的整個事情?)django - 爲什麼request.POST對象是不可變的?
我知道你可以mutify它通過複製發佈數據
post = request.POST.copy()
但爲什麼要這樣做?無論如何,只要讓事情變得可變,肯定會更簡單一些?或者它也被用於其他一些可能導致問題的原因?
正如標題問,爲什麼Django的傢伙決定實施具有的QueryDict的request.POST對象(其中,當然,反過來又使一成不變的整個事情?)django - 爲什麼request.POST對象是不可變的?
我知道你可以mutify它通過複製發佈數據
post = request.POST.copy()
但爲什麼要這樣做?無論如何,只要讓事情變得可變,肯定會更簡單一些?或者它也被用於其他一些可能導致問題的原因?
這有點神祕,不是嗎?一些表面上似是而非的理論被證明是錯了調查:
從而使POST
對象沒有實現突變的方法呢?否:POST
對象屬於django.http.QueryDict
class,該對象實現了全套突變方法,包括__setitem__
,__delitem__
,pop
和clear
。當你調用一個突變方法時,它通過檢查一個標誌來實現不變性。當您調用copy
方法時,您將獲得另一個QueryDict
實例,其中打開了可變標誌。
爲了提高性能?否:當關閉可變標誌時,QueryDict
類不會獲得性能優勢。
這樣POST
對象可以用作字典鍵嗎?編號:QueryDict
對象不可排除。
因此,POST
數據可以建立懶惰(不承諾讀取整個響應),as claimed here?我在代碼中看不到這種證據:據我所知,整個響應總是被讀取,即directly,或者通過MultiPartParser
獲得multipart
響應。
爲了防止編程錯誤?我已經看到這個說法,但我從來沒有看到這些錯誤是什麼的好解釋,以及不變性如何保護你免受它們的侵害。
在任何情況下,POST
是並不總是不變的:當響應是multipart
,然後POST
是可變的。這似乎把kibosh放在你可能想到的大多數理論上。 (除非這種行爲是一個疏忽。)
綜上所述,我看不出有什麼明確的理由在Django爲POST
對象是不可改變的非multipart
請求。
我注意到在Django中有像這樣粗糙的邊緣。不過,在某些時候,一定對某個人有意義。 –
我在另一個Stack中發現了這個答案:「它必須是不可變的,所以它可以被懶惰地構建,拷貝會獲得所有的POST數據,直到拷貝完成時,它可能不會被全部取出。 WSGI服務器工作得相當好,這是有益的,如果這是不可改變的「 – Seaux
@Seaux:請參閱我的要點#4。 –
更新:
加雷思·雷斯是正確的,點1 & 3例無效在這種情況下。雖然我認爲第2點和第4點仍然有效,因此我將在此留下論文。
(我注意到,這兩個金字塔(塔)和Django中的request.POST
對象是某種形式的MultiDict
。因此,也許這是一個比較普遍的做法不是讓request.POST
不可改變的。)
我可以「T代言Django的傢伙,雖然在我看來,這可能是因爲一些原因:
QueryDict
並非如此。request.POST
的情況下,服務器端似乎沒有活動需要更改請求的數據的。因此不變的對象更適合,更不用說它們具有實質性的優勢。dict
鍵,我想
可能是非常有用的地方在Django ..
request.POST
(尤其是第三方插件)時,你可以期望來自用戶的這個請求對象將保持不變。在某些方面,這些原因也是對「不可變vs可變?」的通用答案。題。我確信Django案例中有更多的設計考慮。
最後一種情況非常重要。這關乎安全。這就是爲什麼Django提供'會話',這是短暫的獲取和修改狀態之間的數據的方式。 – CppLearner
你的觀點(1)不能成爲這種情況下的答案,因爲'POST'是一個['QueryDict'對象](https://github.com/django/django/blob/master/django/http/__init__ .py#L371),並且這些對象不會因爲不可變而受益。而你的觀點(3)不能成爲答案,因爲'QueryDict'對象是不可散列的,所以不能用作字典鍵。 –
@GarethRees感謝您指出這些。的確我錯了。我更新了我的答案以糾正這些問題。在我回復之前,我應該更多地關注'QueryDict'。 –
如果請求一個Django form
提交的結果,那麼它是合理的POST爲immutable
以確保數據形式提交和形式驗證之間的完整性。然而,如果請求是不經由一個Django form
提交發送,則POST是mutable
因爲沒有表單驗證。
你總是可以做這樣的事情:(按@leo-the-manic's comment)
# .....
mutable = request.POST._mutable
request.POST._mutable = True
request.POST['some_data'] = 'test data'
request.POST._mutable = mutable
# ......
@JoshK:我猜這個評論者想讓POST變爲可變的,並且這個答案中的代碼片段有所幫助。 – ShreevatsaR
您可以添加新的鍵值,但不能更改現有數據。 –
我發現這在堆棧評論回答https://stackoverflow.com/a/2339963
而且它必須是不可變的,這樣它可以懶洋洋地建造。複製強制獲取所有POST數據。在拷貝之前,它可能不會被全部取出。此外,對於多線程WSGI服務器工作得相當好,這是有幫助的,如果這是不可變的
我喜歡它默認情況下是不可變的。 正如你指出的那樣,如果你需要,你可以使它變化,但你必須明確它。這就像'我知道我可以讓我的表單調試一場噩夢,但我知道我現在正在做什麼。'
爲什麼你想要它是可變的?您可以從中獲取數據並在視圖中使用/修改數據。通過向其添加數據,您可以創建一個「request.POST」已被提交的數據比實際數據更多的印象。 –
這不是我*想*它是可變的。不過,比方說,我想要冰淇淋冷。在冰淇淋的情況下,如果它不冷,它會融化,然後你會因爲製造一個大混亂而被罵。但有了request.POST對象......我的意思是,如果我要搞砸我的代碼,我會把它搞砸。我並不知道有開發人員將數據添加到POST對象和導致問題的特徵,因此定位到「修復」似乎很奇怪。 – bharal
不錯的問題;從來沒有想過它。 –