2012-07-02 68 views
3

我目前正在用django開發一個應用程序,並且每次在渲染視圖或模板時出現錯誤時,我的會話被註銷。這最終是相當惱人的。我如何禁用此功能?請注意,如果在代碼加載/解析時發生錯誤(例如,如果視圖上的裝飾器失敗),那麼只有在視圖中存在錯誤時,我纔不會註銷。django:當請求出現錯誤時,請不要註銷`request.session.set_exipry`

編輯:我只是測試,是的,raise Exception在視圖確實會造成這種情況。

我所有的意見都包裹着一個裝飾,其中,除其他事項外,不:

def needs_base_index_dict(func): 
    def wrapper(request, *args, **kwargs): 
     request.session.set_expiry(30*60) 
     #... 

如果我註釋掉set_expiry線,然後我沒有得到這個行爲。當我修復錯誤時,我仍然登錄。如果該行未被註釋掉,則視圖中的任何錯誤(包括raise Exception())都會將會話記錄在外。

+4

我從來沒有聽說過這個「功能」 - 你可能想看看爲什麼會發生這種情況......你認爲在視圖中引發異常會導致這種情況嗎?動態模板錯誤不會導致我的這種行爲(比如說文件不存在,我得到一個IOError) –

+0

@YujiTomita:檢查編輯 – Claudiu

+0

您使用了哪個會話後端?默認的數據庫後端?此外,你檢查是否存在錯誤頁面的http標題中的cookie? – Jyrsa

回答

4

Django的會話基本上寫入數據庫每次有變化吧。由於您在視圖裝飾器中更新了會話狀態,這意味着應該有會話寫入數據庫。

但是,如果您在使用事務管理的數據庫上,那麼當您的視圖失敗時,您的數據庫寫入會回滾。但是,您的會話cookie過期時間已在您的瀏覽器中更新。這意味着您的瀏覽器會話和存儲在服務器上的會話不再匹配。這種不一致導致會話被丟棄並且您被註銷。

這也解釋了爲什麼當你註釋掉該行時它可以正常工作。

如果您使用django dev服務器,那麼您應該能夠在控制檯中看到您的查詢。發生錯誤時查看會話更新查詢是否成功運行。如果沒有,你會知道你爲什麼要註銷:)

這是所需的行爲,但如果你想在你的調試環境中禁用它,那麼只需在你的裝飾器相關行上面添加一個DEBUG檢查。或者,您可以禁用事務管理(不推薦)。

+0

很好的解釋和良好的解決方案 - 謝謝 – Claudiu

0

你在評論中說,你也可以在錯誤頁面中得到set-cookie標頭。 會話對象看起來好嗎?在sessions documentation它說,你可以像任何其他數據庫對象一樣訪問基於數據庫的會話。

from django.contrib.sessions.models import Session 
s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead') 

如果會話是匿名用戶,然後我願意稱這是一個非常有趣的功能。如果它是一個完全有效的會話,但不知何故,看起來您已不再登錄,但在處理會話cookie方面存在一個錯誤。

3

不是一個答案,爲什麼,但也許是一種解決方法:

def needs_base_index_dict(func): 
    def wrapper(request, *args, **kwargs): 
     #... do the work 
     func(*args, **kwargs) 
     #... then set the expiry 
     request.session.set_expiry(30*60) 
+0

不錯,這個工程。除非我猜想渲染模板時有一個例外。 – Claudiu

相關問題