Django视图中的循环代码:如何避免重复?

2024-04-18 15:36:42 发布

您现在位置:Python中文网/ 问答频道 /正文

对于我的许多视图(但不是所有视图),我必须进行一些验证,以确保登录的用户能够访问他们试图访问的对象。对于30多个视图,我有以下代码:

def whatever_view_name(request, id, access_id):
    check = Access.objects.filter(user=request.user, id=access_id)
    if check:
        access_object = check[0]
    else:
        return redirect(reverse("create_new_access_object"))

    .... and now my view-specific code will follow ...

所以我需要检查这个特定用户是否有特定的数据库记录(Access)。这个代码重复了很多次,这似乎是不对的。我一直在考虑使用中间件,但是有两个问题:a)我需要在视图中使用这个对象(请参见变量access_object,所以我担心如果我将它放在中间件中,我必须查询它两次),以及b)我不必总是这样做,所以我想知道如果这是中间件,如何只对一些视图而不是所有视图运行它。你知道吗

有什么想法吗?你知道吗


Tags: 中间件对象代码用户view视图idobject
2条回答

我能想到的一种方法是使用继承。我们可以将普通的东西重构成一个超级视图类,然后在子视图类中进行扩展。你知道吗

像这样:

我们可以有这样的超级班

class AccessVerifiedView(View):
     def get(self, request, *args, **kwargs):
        check = Access.objects.filter(user=request.user, id=kwargs["access_id"])
        if check:
            access_object = check[0]
            self.verified_get(access_object)
        else:
            return redirect(reverse("create_new_access_object"))

    def verified_get(self, access_object):
        raise NotImplementedError

然后我们可以在视图中扩展这个类和用法。你知道吗

class MyView(AccessVerifiedView):
    def verified_get(self, access_object):
        return access_object

这种方法更具可读性。任何看到代码的人都可以看到超类并理解代码流。你知道吗

其他一些方法是

  1. 装饰师:我们可以有一个装饰师做同样的事情。然后我们可以装饰我们想要验证的视图。你知道吗

您可以为此编写装饰程序:

from functools import wraps

def check_access(function):
  @wraps(function)
  def wrap(request, id, access_id, *args, **kwargs):
        check = Access.objects.filter(user=request.user, id=access_id)
        if check.exists():
             return function(request, id, access_id, *args, **kwargs)
        else:
            return redirect(reverse("create_new_access_object"))
  return wrap

# usage

@check_access
def whatever_view_name(request, id, access_id):
     return ...

相关问题 更多 >