【问题标题】:Django 4.0.2 | Python 3.9.7 | TypeError: __init__() missing 1 required positional argument: 'get_response'Django 4.0.2 | Python 3.9.7 |类型错误:__init__() 缺少 1 个必需的位置参数:'get_response'
【发布时间】:2022-02-20 00:15:19
【问题描述】:

我写了一个自定义的认证,并在认证过程中添加了一个csrf检查中间件。 我在身份验证函数中调用了下面的函数。

def enforce_csrf(self, request):
    """
    Enforce CSRF validation
    """
    check = CSRFCheck()
    check.process_request(request)
    reason = check.process_view(request, None, (), {})
    if reason:
        # CSRF failed, bail with explicit error message
        raise PermissionDenied('CSRF Failed: %s' % reason)

CSRFCheck() 函数是一个自定义中间件,看起来像这样。

class CSRFCheck(CsrfViewMiddleware):
    def _reject(self, request, reason):
        return reason

现在,当我尝试处理需要身份验证的请求时,出现错误:
TypeError: init() missing 1 required positional argument: 'get_response'

相同的代码在 Django 3.2 中完美运行

现在,就我能够调试而言,CSRFCheck 函数需要一个我不知道它来自哪里的 get_response 方法。

【问题讨论】:

标签: python django django-rest-framework csrf


【解决方案1】:

似乎创建自定义中间件的 API 是您在初始化时提供 get_response 参数。

https://docs.djangoproject.com/en/4.0/topics/http/middleware/#writing-your-own-middleware

当您调用 CSRFCheck() 时,您没有提供该参数,因此当它运行时,它会失败。

您可以尝试按照上面链接中的示例并重新格式化您的自定义中间件以匹配他们提供的示例。

【讨论】:

  • 它不完全是一个自定义中间件,我只是扩展了 CSRF 中间件,它没有任何 init 功能。 (检查了 csrf 基本文件)。另外,如果我们同意您的观点,我应该将参数作为 get_response 变量传递什么。
  • 我相信 CsrfViewMiddleware 继承自 MiddlewareMixin ,它具有您正在寻找的 init 。 def enforce_csrf 是视图吗?如果是这样,我认为您不需要从视图中调用中间件,如果您在设置文件docs.djangoproject.com/en/4.0/topics/http/middleware/… 的中间件链中设置它应该会自动调用它
  • 如果你真的想从视图中调用它,那么也许中间件不是你要找的,也许你想要装饰器方法docs.djangoproject.com/en/4.0/ref/csrf/…
  • @artisian 抱歉回复晚了,我的健康状况不佳。不,“enforce_csrf”不是视图。这是一个在身份验证类中调用的普通 python 函数。我从这个博客中获得了一些灵感:dev.to/a_atalla/… 你可以查看它以获得更好的理解。唯一的问题是,我的代码在 django 3.2 中运行良好,并且在 django 4.X 中开始抛出错误。我猜是一些内部库问题。
【解决方案2】:

将 Django 版本降级到 3.2.X 直到修复错误。

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 2021-07-06
    • 2023-03-19
    • 2020-01-29
    • 2017-10-30
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多