在DetailView中为method_decorator编写可调用的

时间:2013-09-04 21:01:54

标签: django django-models django-views

我有一个PrintDetailView,如果打印的to_publish属性设置为True,我希望可以访问打印的所有者,或者任何人。

为了做到这一点,我试图使用一个permission_required()方法装饰器,它接受来自Print模型的可调用:

class PrintDetailView(DetailView):
    template_name = 'prints/detail.html'
    queryset = Print.objects.all()

    @method_decorator(permission_required('prints.user_is_owner_or_public'))
    def dispatch(self, request, *args, **kwargs):    
        return super(PrintDetailView, self).dispatch(request, *args, **kwargs)

以下是Print模型中的user_is_owner_or_public()方法:

def user_is_owner_or_public(self, user):
        """Checks whether the print is a public print, or
        whether the current user is the owner
        """
        if self.user is user or self.to_publish:
            return True

现在,当我在其to_publish属性设置为True的打印详细信息页面上测试时,我仍然看到登录屏幕,所以我知道正在调用permission_required()函数;但是,它显然没有调用user_is_owner_or_public()方法。

任何人都可以让我了解如何使这项工作成功吗?

TIA,Andy

1 个答案:

答案 0 :(得分:2)

这根本不是permission_required所做的 - permission_required是Django权限系统的一部分,并且会导致Django检查权限数据库表以查找已登录用户的适当命名的权限对象(直接授予或通过集团授予)。你要做的是在dispatch周围的装饰器范围之外 - 如果没有别的,你的print实例直到后面的视图才被加载,所以它将无法检查{{1} }。

我要处理的最简单方法是在视图上定义to_publish方法:

get_queryset

那将为用户无法看到的任何打印件抛出404。如果您宁愿重定向到登录页面,则必须覆盖from django.db.models import Q class PrintDetailView(DetailView): template_name = 'prints/detail.html' def get_queryset(self): return Print.objects.filter(Q(user=self.request.user) | Q(to_publish=True)) 方法:

get

作为旁注,如果可以仅从用户对象确定调度方法,则可以使用user_passes_test装饰器添加对调度方法的限制。这在这里没有用,但是如果你的测试只需要用户而不是打印实例那么。