【问题标题】:Middleware not executed by Django没有由 Django 执行的中间件
【发布时间】:2019-06-11 03:46:20
【问题描述】:

我试图在 Django 项目中包含一个中间件,但似乎 Django 没有执行该中间件。这个想法是在拥有应用管理员权限时模拟另一个用户帐户。

我的 settings.py 文件的 MIDDLEWARE 部分如下所示:

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',
    'mird_project.monitor.middleware.impersonateMiddleware.ImpersonateMiddleware',
]

中间件类如下所示:

from .models import Usuario

class ImpersonateMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_request(self, request):

        us_obj = Usuario.objects.all().filter(id_usuario=request.user.username).first()
        tipo = us_obj.tipo.id_tipo

        if tipo == "AD" and "__impersonate" in request.GET:
            request.session['impersonate_id'] = request.GET["__impersonate"]
        elif "__unimpersonate" in request.GET:
            del request.session['impersonate_id']

        if tipo == "AD" and 'impersonate_id' in request.session:
            request.user = Usuario.objects.get(id_usuario=request.session['impersonate_id'])

        return None


我在process_request 方法中插入了一个assert False, request,以便它会异常中止执行并向我显示包含的请求。它甚至从未被执行,所以我假设中间件永远不会被执行。它不会引发任何类型的错误,并且模拟机制只会在站点中显示相同的管理员用户。

任何想法为什么不调用中间件?

【问题讨论】:

  • 你用的是什么版本的 Django?
  • 我使用的是 Django 2.1
  • 你确定路径是对的吗?如果是这样,您的models.pymird_project.monitor.middleware 中,这将是不寻常的。

标签: django middleware


【解决方案1】:

看起来您正在混合使用新旧风格的中间件 API。 process_request() 方法是 Django 1.10 之前的方法,除非您的中间件类使用 MiddlewareMixin,否则不会自动调用。

您需要通过__call__() 方法自己调用process_request()

def __call__(self, request):
    self.process_request(request)  # Call process_request()
    response = self.get_response(request)
    return response

或者你可以从MiddlewareMixin 继承,这样process_request() 就会被Django 调用。但是,只有在需要使中间件向后兼容时才有意义。

【讨论】:

  • 我按照你说的修改了__call__ 函数,这对我来说非常有意义,但它仍然不会被调用。我什至尝试将process_request 函数的主体移动到__call__ 函数中,但它没有被调用。我还能尝试什么?
  • 您是否尝试将assert False 作为__call__ 本身的第一行?
  • 我有一个assert False, request.GET 作为__call__ 的第一行。
  • 另外,如 cmets 中所述,您的模型导入似乎是通过相对导入从 mird_project.monitor.middleware.middleware 包中导入的。也许你的意思是from mird_project.monitor.models import Usuario
  • 是的,很抱歉,我现在相应地修改了导入。
猜你喜欢
  • 2016-12-10
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多