如何使用Django装饰器

时间:2015-07-03 02:27:00

标签: django

我正在研究Django项目并试图找出如何测试用户所有权并允许根据结果进行编辑或重定向。

我有一个模型SceneSceneUser相关联,以跟踪哪位用户创建了特定的Scene

class Scene(models.Model):
    user = models.ForeignKey(User)
    [rest of Scene model]

我有一个URL模式来编辑特定的Scene对象,如下所示:

url(r'^scenes/(?P<pk>[0-9]+)/edit/', SceneUpdateView.as_view(), name='scene-edit'),

我通过django-allauth登录了用户。我只希望Scene所有者能够修改Scenes

我试图找出如何使用装饰器来测试网址调用的特定场景是否为scene.user.id == self.request.user.id

我是否需要将网址信息发送到permission_requireduser_passes_test装饰器(这可能)吗?

我怎样才能实现这一目标?

1 个答案:

答案 0 :(得分:4)

您可以使用自定义装饰器来满足您的需求。 注意:我使用基于函数的视图,如果需要,您必须将代码修改为基于类的视图:

import json

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth.models import User
from yourmodels.models import Scene

#Custom decorator
def must_be_yours(func):
    def check_and_call(request, *args, **kwargs):
        #user = request.user
        #print user.id
        pk = kwargs["pk"]
        scene = Scene.objects.get(pk=pk)
        if not (scene.user.id == request.user.id): 
            return HttpResponse("It is not yours ! You are not permitted !",
                        content_type="application/json", status=403)
        return func(request, *args, **kwargs)
    return check_and_call

#View Function
@must_be_yours
@csrf_protect
def update_scene(request, pk=None):
    print pk
    if request.method == 'PUT':
        #modify merely
        pass

的url:

url(r'^scenes/(?P<pk>[0-9]+)/edit/', 'update_scene'),