Python 如何在 Django 中设置自定义中间件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18322262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set up custom middleware in Django
提问by Atma
I am trying to create middleware to optionally pass a kwarg to every view that meets a condition.
我正在尝试创建中间件以选择性地将 kwarg 传递给满足条件的每个视图。
The problem is that I cannot find an example of how to set up the middleware. I have seen classes that override the method I want to, process_view
:
问题是我找不到如何设置中间件的示例。我见过覆盖我想要的方法的类process_view
:
Class CheckConditionMiddleware(object):
def process_view(self, request):
return None
But where do I put this class? Do I create a middleware app and put this class inside of it and then reference it in settings.middleware
?
但是我把这门课放在哪里?我是否创建了一个中间件应用程序并将此类放入其中,然后在其中引用它settings.middleware
?
采纳答案by AlvaroAV
First: The path structure
第一:路径结构
If you don't have it you need to create the middlewarefolder within your app following the structure:
如果您没有它,您需要按照以下结构在您的应用程序中创建中间件文件夹:
yourproject/yourapp/middleware
The folder middleware should be placed in the same folder as settings.py, urls, templates...
文件夹中间件应该和settings.py、urls、templates...放在同一个文件夹中。
Important: Don't forget to create the __init__.py empty file inside the middleware folder so your app recognize this folder
重要提示:不要忘记在中间件文件夹中创建 __init__.py 空文件,以便您的应用程序识别此文件夹
Second: Create the middleware
二:创建中间件
Now we should create a file for our custom middleware, in this example let's supose we want a middleware that filter the users based on their IP, we create a file called filter_ip_middleware.pyinside the middlewarefolder with this code:
现在我们应该为我们的自定义中间件创建一个文件,在这个例子中,假设我们想要一个根据用户的 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
Third: Add the middleware in our 'settings.py'
第三:在我们的“settings.py”中添加中间件
We need to look for:
我们需要寻找:
MIDDLEWARE_CLASSES
(django < 1.10)MIDDLEWARE
(django >= 1.10)
MIDDLEWARE_CLASSES
(django < 1.10)MIDDLEWARE
(Django >= 1.10)
Inside the settings.py and there we need to add our middleware (Add it in the last position). It should be like:
在 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'
)
Done !Now every request from every client will call your custom middleware and process your custom code !
完毕 !现在来自每个客户端的每个请求都会调用您的自定义中间件并处理您的自定义代码!
回答by user6061091
It will be helpful in the case of When you know what type of Exception occurs in the views. From the above I have Created my own Custom class like
当您知道视图中发生什么类型的异常时,这将很有帮助。从上面我创建了自己的自定义类
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"
It will be executed when the exception occur in the case of string and integer addition.
在字符串和整数加法的情况下发生异常时会执行。
You can write Corresponding views for above middleware class
您可以为上述中间件类编写相应的视图
回答by W.Perrin
Just two steps. It works for me with django2.1
.
只需两步。它对我有用django2.1
。
1.Create your own Middleware class.
1.创建自己的中间件类。
There is a good demo from official manual.
官方手册中有一个很好的演示。
https://docs.djangoproject.com/en/2.1/ref/request-response/#django.http.HttpRequest.get_host
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()
2.Reference your Middleware class in the MIDDLEWARE
list of your project setting.py
file.
2.在MIDDLEWARE
您的项目setting.py
文件列表中引用您的中间件类。
The rule for Middleware reference is the path to your class from the root directory of your project.
中间件引用的规则是从项目根目录到您的类的路径。
For example, in a project named mysite
,the tree is as follow.
例如,在名为 的项目中mysite
,树如下所示。
├── mysite
│?? ├── manage.py
│?? ├── mysite
│?? │?? ├── __init__.py
│?? │?? ├── middleware.py
│?? │?? ├── settings.py
│?? │?? ├── urls.py
│?? │?? └── wsgi.py
We just add our Middleware class MultipleProxyMiddleware
in the middleware.py
file. We get the following reference name.
我们只是MultipleProxyMiddleware
在middleware.py
文件中添加我们的中间件类。我们得到以下引用名称。
MIDDLEWARE = [
'mysite.middleware.MultipleProxyMiddleware',
...
]