像python django中的宏功能

时间:2014-10-22 17:09:02

标签: python django macros

我有一些django视图处理函数,其结构类似于

def view1(request):

  # Check for authorization
  if not isAuthorized(request):
    return HttpResponse('Foo error', status=401)

  return HttpResponse('view1 data')


def view2(request):

  # Check for authorization
  if not isAuthorized(request):
    return HttpResponse('Foo error', status=401)

  return HttpResponse('view2 data')


def view3(request):

  # Check for authorization
  if not isAuthorized(request):
    return HttpResponse('Foo error', status=401)

  return HttpResponse('view3 data')

我想做这个部分:

  # Check for authorization
  if not isAuthorized(request):
    return HttpResponse('Foo error', status=401)

某种单行,所以我不必在每个视图中重复它

在C中这可能是一个宏,但我不知道如何在python中实现类似的东西

检查授权功能部分是一个例子,它可以是任何与用户授权无关的检查

[编辑]

https://stackoverflow.com/users/2337736/peter-deglopper提到装饰者......

详细说明

我有一个可以接受POST或GET的Web API

# return either GET or POST dict whichever exists
def getParams(request):
    if request.method == 'GET':
        return request.GET
    return request.POST

观点是这样做的:

def someAPI(request):
  dct = getParams(request)

  if not isValid(dct):
    return HttpResponse('Bad request', status=401)

我怎么能用装饰器来实现这一点?我之间有getParams()函数....

2 个答案:

答案 0 :(得分:2)

通常你会使用视图装饰器: https://docs.djangoproject.com/en/dev/topics/http/decorators/

内置一个用于检查登录状态的内容: https://docs.djangoproject.com/en/1.7/topics/auth/default/#the-login-required-decorator

一个用于对经过身份验证的用户进行任意测试: https://docs.djangoproject.com/en/1.7/topics/auth/default/#django.contrib.auth.decorators.user_passes_test

改编自http://mrcoles.com/blog/3-decorator-examples-and-awesome-python/的完整示例:

from functools import wraps

def validate_params(view_func):
    def _decorator(request, *args, **kwargs):
        dct = getattr(request, request.METHOD)
        if not isValid(dct):
            return HttpResponse('Bad request', status=401)
        else:
            response = view_func(request, *args, **kwargs)
            return response
    return wraps(view_func)(_decorator)

我在getattr使用if/then而不是request.METHOD - 我认为更干净。如果您愿意,您仍然可以使用getParams来电。

答案 1 :(得分:2)

正如彼得所说,装饰者是一个理想的解决方案。但另一种方法是使用基于类的视图:您可以定义执行检查的基类,以及实现特定行为的子类。