2012-02-22 62 views
4

我有一個看起來像這樣的功能基礎觀點:Django的 - 過濾於的DetailView

def account_details(request, acc_id): 
    account = get_object_or_404(Account, pk=acc_id, person__user=request.user) 
    # ... 

它會顯示您的帳戶上成功的細節,以及404,如果你沒有權限訪問該帳戶或它不存在。

我試圖用(擴展的DetailView)一類基於視圖實現相同,以及與此想出了:

class AccountDetailView(DetailView): 
    def get_object(self, queryset=None): 
     obj = super(AccountDetailView, self).get_object(queryset) 
     if obj.person.user != self.request.user: 
      raise Http404() 
     return obj 

URL配置:

url(r'^account_details/(?P<pk>[0-9a-f]{24})$', 
    login_required(AccountDetailView.as_view(model=Account)), 
    name='account_details'), 

這種態度工作,但介紹2個額外的查詢,看起來不對。

是否有標準或更優雅的方式來實現相同的結果?

+0

我的第一個想法是重寫'get_queryset()',但它不接受參數 - 無法檢查帳戶pk ... – yprez 2012-02-22 21:23:35

+1

btw,你有權訪問關鍵字args在通過'self.kwargs'分類的視圖中 – 2012-02-23 00:42:21

回答

14

無論如何你需要傳遞什麼參數到get_queryset?這應做到:

def get_queryset(self): 
    qs = super(MyView, self).get_queryset() 
    return qs.filter(person__user=self.request.user) 
+0

佛有些原因,我認爲它不會被PK正確過濾,謝謝。 – yprez 2012-02-22 22:10:19

2

如果你所擔心的查詢,你可以使用select_related預取用戶配置文件中的查詢集:

def get_queryset(self) 
    return Account.objects.select_related("person", "person__user").all() 

def get_object(self, queryset=None): 
    try: 
     return queryset.get(pk=self.kwargs['acc_id'], person__user=self.request.user) 
    except Account.DoesNotExist: 
     raise Http404 

我不得不說,它有時很難得到東西,以適應基於類的視圖

+1

我也注意到了。大多數情況下,我喜歡基於類的視圖,但是這裏有一些簡單的事情,比如將處理傳遞給另一個視圖(基於函數的視圖非常容易),這些視圖現在已經接近惡魔般的困難了。 – 2012-02-22 22:40:06