2012-02-22 63 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