【问题标题】:macro like functionality in python djangopython django中的类似宏的功能
【发布时间】:2014-10-22 17:09:02
【问题描述】:

我有一些像这样结构的 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() 函数....

【问题讨论】:

    标签: python django macros


    【解决方案1】:

    通常你会为此使用视图装饰器: 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)
    

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

    【讨论】:

    • 正如我所说,这不是 django 用户身份验证特定的。我想运行一个任意函数来检查请求中的 GET/POST 并有时返回错误。装饰器可以做到这一点吗?
    • 是的 - 如果您检查方法 required 装饰器的来源,您将看到一个基于 request 返回错误响应的示例。 docs.djangoproject.com/en/dev/_modules/django/views/decorators/…
    • 虽然这比你可能需要的要复杂一些,因为装饰器本身需要参数。如果您想一直进行相同的检查,这里的“基本装饰器”示例对我来说很合适:mrcoles.com/blog/3-decorator-examples-and-awesome-python
    • 编辑了一个示例,展示了如何集成参数检查。
    • 工作就像一个魅力!谢谢一百万!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 2020-09-23
      • 2017-05-06
      相关资源
      最近更新 更多