我一直在嘗試使用Django條件視圖處理功能。基本上我想拒絕一個實體的更新操作,如果它已經被另一個用戶修改過,並且這似乎與Django提供的@condition修飾器很好地工作。Django條件視圖處理裝飾器添加陳舊Etag
但是有一個問題是我在測試時注意到的,後來我檢查了Django的源代碼,發現我認爲可能是一個bug,但只是想在這裏先確認一下,然後向Django提交bug報告,固定。
裝飾器在新請求進入時調用,它首先根據傳入裝飾器的函數計算ETag和上次修改時間戳,然後將控制權交給get_conditional_response()
函數。這裏將執行ETag和上次修改的驗證,如果它們與請求中提供的內容不匹配,請求將被拒絕。到現在爲止還挺好。
如果檢查通過,則允許請求並調用視圖來處理請求並生成響應。在處理請求時,如果這是一種不安全的方法,例如PUT
或PATCH
,它會更新實體,這很可能會更改ETag和Last Modified值。
然而,我注意到,到PUT
或PATCH
成功響應發送回用的ETag或最後修改時間戳計算之前實際進行了更新,而現在這些值是無效或失效。這對我來說似乎是錯誤的。在同一實體上執行新的GET
,然後在響應中向用戶提供更新的ETag和Last Modified值。
難道你不認爲condition()
修飾器應該檢查請求方法是否不安全,那麼它應該在視圖處理後重新計算ETag和Last Modified,然後將新值添加到響應中?
感謝您的詳細解答。我同意,不發送任何ETag來響應PUT請求比發送過時/無效的ETag要好得多。 – Safi
我想這取決於視圖的具體實現,例如在我的情況下,在成功處理PUT請求時,視圖將響應200 OK並且響應主體包含更新的資源表示。與此響應一起發送一個ETag將爲客戶端保存一個額外的GET請求,以獲取更新後的ETag以用於將來的條件請求。 然而,您的建議更加保守,並且與RFC更符合。我會創建一張票。 – Safi
@Safi:您可以隨時在您的視圖中自行添加ETag標題。或者你可以編寫自己的裝飾器來包裝'condition()'並添加ETag。 –