我的视图装饰器将项目添加到传递给视图函数的kwargs是否“没问题”?

时间:2017-05-25 05:45:14

标签: python django django-views python-decorators

我写了一个装饰器来包装我的很多观点。它基本上检查request.user是否是对象的“所有者”。

# urls.py
...
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.my_view, name='my_view'),
]


# decorators.py
...
def user_can_access_object(function):
    def wrap(request, *args, **kwargs):
        my_object = get_object_or_404(MyModel, pk=kwargs['pk'])

        if request.user == my_object.owner:
            # I actually do more to ensure the user can access, but this is for my SO question to keep it simple.
            kwargs['my_object'] = my_object  # <-- Am I doing something terrible here?
            return function(request, *args, **kwargs)

        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


# views.py
...
@login_required
@user_can_access_object
def my_view(request, pk, my_object):  # Now that 'my_object' is set, my_view must be setup to accept it. Also, 'pk' is the pk for my_object.
    """"
    A view that does something to 'my_object'.

    """
    ...
    some_function(my_object)
    ...
    return render(request, "my_template.html", some_context)

这是我最初的解决方案。

# decorators.py
...
def user_can_access_object(function):
    def wrap(request, *args, **kwargs):
        my_object = get_object_or_404(MyModel, pk=kwargs['pk'])

        if request.user == my_object.owner:
            return function(request, *args, **kwargs)

        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


# views.py
...
@login_required
@user_can_access_object
def my_view(request, pk):  # This seems to be better, or at least more clear, It seems like the decorator is playing nicely and not modifying the request kwargs.
    """"
    A view that does something to 'my_object'.

    """
    my_object = MyModel.objects.get(pk=pk)  # My concern is that 'my_object' is looked up twice. And that seems gross and isn't this an extra database query?
    ...
    some_function(my_object)

    return render(request, "my_template.html", some_context)

我最担心的是,当my_object添加到kwargs时,它基本上会使装饰器上的视图依赖。这似乎是不好的做法,但也许不是。

0 个答案:

没有答案