对于我的许多视图(但不是全部),我必须进行一些验证,以确保登录的用户能够访问他们试图访问的对象。对于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)我不需要总是这样做,所以我想知道如何只对一些视图运行它,如果这是中间件的话,这不是全部。
有什么想法吗?
发布于 2019-06-20 09:31:44
您可以为此编写一个装饰器:
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 ...发布于 2019-06-20 09:16:55
我能想到的一种方法是使用继承。我们可以将常见的内容重构成一个超级视图类,然后在子视图类中扩展相同的内容。
就像这样:
我们可以有一个这样的超级班
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这种方法看上去更具可读性。任何看到代码的人都可以看到超类并理解代码流。
其他几种方法是
https://stackoverflow.com/questions/56682299
复制相似问题