2013-12-20 30 views
1

我的Django應用程序中的每個用戶都與一個部門相關聯,幾乎每個請求都涉及與部門相關的處理。所以我很想讓部門對象在整個應用程序中都可用。Django中間件,會話和緩存入門

其中哪些,如果有的話,是最合適的方法採取:

  1. 定製中間件,簡單地檢索來自DB相關部門,並將其附加到request對象,說的那樣request.department,有點兒像Django的AuthenticationMiddleware使當前登錄的用戶可用request.user。 (例如,請參閱herehere
  2. 當用戶登錄時,將部門置於會話中,然後使用Django的request.session界面在視圖中檢索該部門。

我還沒有機會熟悉Django的緩存功能,但我想最終緩存每個用戶的部門,以避免每個請求額外的數據庫命中。我看到Django's sessions provide built-in caching support。我也想象緩存可以用第一種方法來實現。

使用會話(上面的#2)超過自定義中間件(上面#1)這種事情是否有優勢?從內部API的角度來看,中間件方法看起來更清潔,但我猜這正是會話設計的那種 - 所以也許這是開始使用它們的合適機會?

感謝您的任何指導!

回答

1

基本上兩種方法都非常相似。 request.session方法可以通過手動設置中間件中的緩存來消除額外的步驟。會話方法的壞處在於,如果您使用緩存存儲,數據不能保證可用。例如,可以有0.1%的用戶被禁用Cookie,您正在使用memcache存儲,在重新部署時可能需要重新啓動您的memcache服務器,並且您登錄的用戶將丟失他們的數據等等。總之,我不會使用會話與高速緩存存儲關鍵數據。在我的項目中,我更喜歡使用第一個選項,因爲它給了我更大的控制權。

最多可以設置有專門的中間件將view_name變量的請求,並允許控制在何處以及如何顯示:

class NameMiddleware(object): 
    def process_view(self, request, view_func, view_args, view_kwargs): 
     # add current view 
     if isinstance(view_func, str): 
      request.view_name = view_func 
     elif hasattr(view_func, '__name__'): 
      request.view_name = view_func.__name__ 

然後,你將不得不在這裏向提供附加信息的更大的控制權要求,例如在context_processors您可以附加部門INF只對選定的意見,並以高效的方式緩存結果(代理方式對數據庫的要求,如果你想):

def department_context_processor(request): 
    if hasattr(request, 'view_name'): 
     if request.view_name == 'department_view1' or request.view_name == 'department_view2': 
      departments = cache.get('department_'+str(request.user), None) 
      if departments is None: 
       departments = Department.objects.filter(user=request.user) 
       cache.set('department_'+str(request.user), departments, 60*60) 
      if departments: 
       return { 
        'departments': departments 
       } 
    return {} 
+0

感謝您的建議和反饋,Dmytriy !真的很有幫助。這是一種使用基於cookie的會話數據存儲的用例可能工作正常嗎?由此,我的意思是將部門本身存儲在cookie中。如果我理解正確,那會導致會話數據的緩存不必要 - 數據將在每個請求中由客戶端發送(並可用於服務器)。 – tino

+0

@tino是的,如果你的數據非常簡單,你不想搞亂緩存。請記住,使用基於cookie的會話幾乎沒有什麼重大限制。例如,每個域的cookie大小有4Kb限制,可以在[這裏]找到更詳細的比較(http://stackoverflow.com/a/18240232/1255305)。無論如何,如果您要使用基於Cookie的存儲,您應該在用戶清除Cookie並且他們不在請求中時處理用例,並確保您不會將任何隱私到部門信息存儲在Cookie中,因爲它們可能會被黑客入侵。 –

+0

明白了。再次感謝。我也讚賞緩存示例。 – tino