如何在django中设置自定义中间件

Atm*_*tma 70 python django django-middleware django-views

我正在尝试创建中间件,以便可选地将kwarg传递给满足条件的每个视图.

问题是我找不到如何设置中间件的示例.我见过的类覆盖了我想要的方法,process_view:

Class CheckConditionMiddleware(object):  
    def process_view(self, request):  

        return None  
Run Code Online (Sandbox Code Playgroud)

但是我把这个课程放在哪里?我是否创建了一个中间件应用程序并将此类放在其中,然后在settings.middleware中引用它?

Alv*_*oAV 119

第一:路径结构

如果您没有它,则需要在应用程序中按照结构创建中间件文件夹:

yourproject/yourapp/middleware
Run Code Online (Sandbox Code Playgroud)

文件夹中间件应与settings.py,urls,templates放在同一个文件夹中...

重要提示:不要忘记在中间件文件夹中创建__init__.py空文件,以便您的应用识别此文件夹

第二:创建中间件

现在我们应该为我们的自定义中间件创建一个文件,在这个例子中,我们想要一个基于IP过滤用户的中间件,我们使用以下代码在中间件文件夹中创建一个名为filter_ip_middleware.py的文件:

class FilterIPMiddleware(object):
    # Check if client IP is allowed
    def process_request(self, request):
        allowed_ips = ['192.168.1.1', '123.123.123.123', etc...] # Authorized ip's
        ip = request.META.get('REMOTE_ADDR') # Get client IP
        if ip not in allowed_ips:
            raise Http403 # If user is not allowed raise Error

       # If IP is allowed we don't do anything
       return None
Run Code Online (Sandbox Code Playgroud)

第三:在'settings.py'中添加中间件

我们需要寻找:

  • MIDDLEWARE_CLASSES (django <1.10)
  • MIDDLEWARE (django> = 1.10)

在settings.py中,我们需要添加我们的中间件(在最后位置添加它).应该是这样的:

MIDDLEWARE = ( #  Before Django 1.10 the setting name was 'MIDDLEWARE_CLASSES'
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
     # Above are django standard middlewares

     # Now we add here our custom middleware
     'yourapp.middleware.filter_ip_middleware.FilterIPMiddleware'
)
Run Code Online (Sandbox Code Playgroud)

做完了!现在,每个客户的每个请求都会调用您的自定义中间件并处理您的自定义代码!

  • 如果遇到以下情况,请检查[this answer](/sf/answers/2956324941/):`TypeError:object()不带任何参数` (4认同)

W.P*_*rin 6

只需两步。它对我有用django2.1

1.创建自己的中间件类。

官方手册中有一个很好的演示。

https://docs.djangoproject.com/en/2.1/ref/request-response/#django.http.HttpRequest.get_host

    from django.utils.deprecation import MiddlewareMixin

    class MultipleProxyMiddleware(MiddlewareMixin):
        FORWARDED_FOR_FIELDS = [
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED_HOST',
            'HTTP_X_FORWARDED_SERVER',
        ]

        def process_request(self, request):
            """
            Rewrites the proxy headers so that only the most
            recent proxy is used.
            """
            for field in self.FORWARDED_FOR_FIELDS:
                if field in request.META:
                    if ',' in request.META[field]:
                        parts = request.META[field].split(',')
                        request.META[field] = parts[-1].strip()
Run Code Online (Sandbox Code Playgroud)

2.在MIDDLEWARE您的项目setting.py文件列表中引用您的中间件类。

中间件引用的规则是从项目根目录到您的类的路径。

例如,在名为 的项目中mysite,树如下所示。

??? mysite
?   ??? manage.py
?   ??? mysite
?   ?   ??? __init__.py
?   ?   ??? middleware.py
?   ?   ??? settings.py
?   ?   ??? urls.py
?   ?   ??? wsgi.py
Run Code Online (Sandbox Code Playgroud)

我们只是MultipleProxyMiddlewaremiddleware.py文件中添加我们的中间件类。我们得到以下引用名称。

MIDDLEWARE = [
    'mysite.middleware.MultipleProxyMiddleware',  
     ...
]
Run Code Online (Sandbox Code Playgroud)


Roa*_*efs 6

在 Django 中编写中间件>=1.10

从 Django 1.10 开始,中间件类必须get_response在其__init__()方法中接受一个参数并提供一个__call__()方法。虽然这可以通过使用django.utils.deprecation.MiddlewareMixinwhen 定义中间件类来实现(W.Perrin回答所示),但在当前支持的 Django 版本中创建基于类的中间件如下所示:

class CustomMiddleware(object):
    def __init__(self, get_response):
        """
        One-time configuration and initialisation.
        """
        self.get_response = get_response

    def __call__(self, request):
        """
        Code to be executed for each request before the view (and later
        middleware) are called.
        """
        response = self.get_response(request)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Called just before Django calls the view.
        """
        return None

    def process_exception(self, request, exception):
        """
        Called when a view raises an exception.
        """
        return None

    def process_template_response(self, request, response):
        """
        Called just after the view has finished executing.
        """
        return response
Run Code Online (Sandbox Code Playgroud)

process_view()process_exception()并且process_template_response()是特殊的钩,处理中间件时Django的调用,您可以在您的中间件类中定义。在上面的例子中,实现的钩子除了确保 Django 将调用下一个中间件来进一步处理响应/请求外,不会做任何特别的事情。

激活中间件

要激活中间件组件,请将其添加到MIDDLEWAREDjango 设置的列表中。

MIDDLEWARE = [
    # Default Django 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',

    # Add your custom middleware
    'path.to.your.middleware.CustomMiddleware',
]

Run Code Online (Sandbox Code Playgroud)