【问题标题】:Django exception middleware: TypeError: object() takes no parametersDjango异常中间件:TypeError:object()不带参数
【发布时间】:2017-07-03 02:58:18
【问题描述】:

我正在使用 Django 1.10 并尝试使用异常中间件捕获所有异常。

以下代码导致内部服务器错误:

mw_instance = middleware(handler)
TypeError: object() takes no parameters

views.py

from django.http import HttpResponse

def my_view(request):
    x = 1/0 # cause an exception
    return HttpResponse("ok")

settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'myproject.middleware.ExceptionMiddleware',  

]

中间件.py

from django.http import HttpResponse

class ExceptionMiddleware(object):
    def process_exception(self, request, exception): 
        return HttpResponse("in exception")

我已经看到这些object() takes no parameters in django 1.10 和其他关于中间件与中间件类的问题,但我不确定这如何适用于这种情况,或者我实际上需要更改什么来解决问题。

【问题讨论】:

    标签: django django-middleware


    【解决方案1】:

    在较新版本的Django中,中间件应该是这样写的

    import datetime
    from django.core.cache import cache
    from django.conf import settings
    from django.utils.deprecation import MiddlewareMixin
    
    class ActiveUserMiddleware(MiddlewareMixin):
    
        def process_request(self, request):
            current_user = request.user
            if request.user.is_authenticated:
                now = datetime.datetime.now()
                cache.set('seen_%s' % (current_user.username), now, 
                               settings.USER_LASTSEEN_TIMEOUT)
    

    【讨论】:

    • 请提供版本好吗?我认为这可能是有用的信息
    • 与 Django 版本 3.0.2
    • 你不应该使用这个,这是 from django.utils.deprecation import MiddlewareMixin 的旧方法,即使你的导入也建议弃用。
    【解决方案2】:

    由于您使用新的MIDDLEWARE 设置,您的中间件类必须接受get_response 参数:https://docs.djangoproject.com/en/1.10/topics/http/middleware/#writing-your-own-middleware

    你可以这样写你的类:

    from django.http import HttpResponse
    
    class ExceptionMiddleware(object):
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
            return self.get_response(request)
    
        def process_exception(self, request, exception): 
            return HttpResponse("in exception")
    

    您还可以使用 MiddlewareMixin 使您的中间件与 1.10 之前和 1.10 之后的 Django 版本兼容:https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware

    from django.http import HttpResponse
    from django.utils.deprecation import MiddlewareMixin
    
    class ExceptionMiddleware(MiddlewareMixin):
        def process_exception(self, request, exception):
            return HttpResponse("in exception")
    

    【讨论】:

    • 使用MiddlewareMixin 解决了我的问题。
    • Django1.11 中的MiddlewareMixin 将无法确定request.user。它返回匿名
    • @Sarit 的评论有多真实?解决方法是什么?
    • @Phares 当时很好奇,做私下实验。我没有解决任何问题。通常我会在ViewSet
    • 只需添加 MiddlewareMixin 即可为我工作。甚至不需要接触 init 和 call 函数。
    猜你喜欢
    • 2017-10-02
    • 2019-02-05
    • 2012-06-26
    • 2013-06-09
    • 2019-10-17
    • 2020-01-02
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多