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


79

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

问题是我找不到如何设置中间件的示例。我已经看到了覆盖我想要的方法的类process_view

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

        return None  

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


2
:你可以在这里按照我的答案之一stackoverflow.com/questions/17751163/...
总管Hieu阮

虽然这是一个很好的答案,但您也可以阅读django图书
karthikr,2013年

您可以执行以下操作:stackoverflow.com/questions/17751163/…–
Atma

@karthikr您提供的链接断开了:/
fedorqui'停止伤害

Answers:


137

第一:路径结构

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

yourproject/yourapp/middleware

文件夹中间件应与settings.py,url,模板...放置在同一文件夹中。

重要提示:不要忘记在中间件文件夹中创建__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

第三:在我们的“ 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'
)

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


文件的路径正确吗?应该不是您的项目/您的应用/中间件吗?
tiagovrtr

是@tiagovrtr路径应该是yourproject/yourapp/middleware。我以为这很明显,但是如果可以将其清除,我会进行更新
AlvaroAV

9
如果您遇到以下情况,请检查此答案TypeError: object() takes no parameters
T. Christiansen

3

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

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

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

https://docs.djangoproject.com/zh-CN/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()

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

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

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

├── mysite
│   ├── manage.py
│   ├── mysite
│   │   ├── __init__.py
│   │   ├── middleware.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py

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

MIDDLEWARE = [
    'mysite.middleware.MultipleProxyMiddleware',  
     ...
]

-3

当您知道视图中发生什么类型的异常时,这将很有帮助。从上面我创建了自己的Custom类,例如

from .models import userDetails

class customMiddleware(object):

    def process_request(self,request):
        result=''
        users = userDetails.objects.all()
        print '-->',users ,'---From middleware calling ---'

        username=request.POST.get("username")
        salary = request.POST.get("salary")
        if salary:
            try:
                result = username+int(salary)
            except:
                print "Can't add"

如果字符串和整数相加,则在发生异常时执行。

您可以为上述中间件类编写相应的视图

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.