我有主要的urls.py,其中包括其他应用程序urls.py,然后调用相应的视图。但是,无论应用程序如何,我都会在执行任何操作之前每次都执行一项操作。是否可以在路由到视图之前执行操作?
是的,你在这里描述的是middleware [Django-doc]。您可以将中间件视为一组装饰器,它们包含在每个请求 - 响应周期中:因此,您可以在请求传递给视图之前以及响应从视图返回之后自由执行某些任务。
事实上,您可能已经在不知情的情况下使用了大量中间件:例如,用于检查用户是否已登录的身份验证中间件,并将其添加到请求中。
您可以通过定义类来定义自己的中间件,例如在app/middleware.py
中(取自文档,稍作修改):
# app/middleware.py
class MyMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
# ... (pre) ...
response = self.get_response(request)
# ... (post) ...
# Code to be executed for each request/response after
# the view is called.
return response
在这里get_response
是它下面的装饰者(最终它是你正在查询的视图)。因此,您可以在注释(pre)
和(post)
中添加操作(分别在控制传递给视图之前和之后的操作)。
然后,您可以在settings.py
文件中注册您的中间件:
# 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',
'app.middleware.MyMiddleware'
]
# ...
请注意,顺序很重要:例如,AuthenticationMiddleware
会将user
添加到request
对象中。如果你在MyMiddleware
之前运行AuthenticationMiddleware
(把它放在列表中更高的位置),你就不能使用request.user
,除非你自己实现它,但这当然只会导致重复的代码。
在某些项目中,可以省略一些中间件。例如,如果您的项目不需要身份验证,那么某些中间件只会使请求响应过程变慢。通过“抛出”相关的中间件,您可以减少在request
到达视图之前完成的工作量(并且在视图提供的响应返回给客户端之前)。
默认情况下,Django已经在settings.py
文件中添加了一些中间件。您可以在source code [GitHub]中检查(大部分)此中间件的实现。