django中间件可以解决什么问题?

时间:2018-09-22 19:14:32

标签: python django

我是django中间件的初学者。我曾经通过中间件编写访问者系统,但仍然没有遇到可以用中间件解决的问题。您能用django中间件描述任何典型的任务吗?以及必须使用中间件的任务

3 个答案:

答案 0 :(得分:3)

中间件是在服务器和客户端交互之间发生的动作。本质上,它们只是在主服务器逻辑发生之前和之后服务器接收到请求时执行的功能。如果您需要对每个或大多数请求执行某些操作或检查(或一组操作/检查),它们将非常有用。

身份验证是一个很好的例子。您可以在服务器上的每个视图函数中明确执行认证检查,但这不是很干,这会使每个视图函数的主要逻辑变得混乱,如果您忘记了路由该怎么办?相反,您可以编写一个中间件来检查用户是否已登录。如果是,则按常规传递请求。如果不是,请将其重定向到登录页面。另一个示例是Django的内置CSRF protection middleware

装饰器是打包功能并将功能添加到功能中的另一种方法,而无需在需要它的每个功能中重写相同的代码。中间件几乎是相同的想法,只是它们是自动添加的,而装饰器需要添加到每个单独的函数中,并且随着每个视图所需功能的增加,这会变得很麻烦。在服务器中,仅当提供的功能相对独特时才使用装饰器(仅少数路由需要使用装饰器)。

要清楚,中间件是您无法没有的,但是它们为您的代码提供了更好的结构,并使您的服务器更具可伸缩性。

答案 1 :(得分:2)

我不确定您了解什么是Django的中间件。它不像IBM's definition of middleware

Django的中间件的范围要小得多,并且允许您在浏览器请求和业务逻辑之间(或反之)在业务逻辑和对浏览器的响应(或两者)之间执行任务。

典型任务是:

  • 在请求对象进入视图之前将其放入信息(有关示例,请参见AuthenticationMiddleware)
  • 验证传入的请求
  • 在响应中添加标题
  • 拦截并重新格式化异常

答案 2 :(得分:1)

您可以在每个视图周围看到中间件作为隐式装饰器的列表。简而言之,中间件软件因此用于预处理请求后处理响应。例如,它还可以用于执行诊断(测量请求和响应之间的时间)。

在特定视图处理HttpRequest之前和视图生成的HttpResponse发送给客户端之前,中间件(可以)与请求进行交互,或者对响应进行后处理。

一个常见的示例是身份验证系统。默认情况下,这是设置在MIDDLEWARE列表中的中间件。您可能经常使用request.user做某事,但是该属性从何而来?它由django.contrib.auth.middleware.AuthenticationMiddleware [GitHub]添加到request

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE%s setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        ) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
        request.user = SimpleLazyObject(lambda: get_user(request))

如您所见,它通过添加属性request修补request.user = ...。没有这种中间件,HttpRequest将不会携带(延迟获取)用户。

中间件的另一个示例可能是一个系统,该系统可以测量每个视图所花费的时间,并将其记录到控制台:在获取请求时,例如,它会在请求进入视图之前以及获取视图时将时间戳附加到请求响应,看起来已经过去了多少时间。

也可以进行后处理响应。想象一下,您每次都想在HTTP响应中设置某个cookie,那么再次使用中间件绝对是个好主意。

例如,您可以实现中间件,该中间件跟踪(每个用户)访问某个页面的次数,从而将数据存储在某个位置(文件,内存,数据库等)。

当然,严格来说,您当然可以在视图(或视图的装饰器)中执行此类操作,但这意味着您需要将装饰器添加到需要此视图的所有可能的视图中。想象一下,如果以后您决定不再在您的站点上拥有用户,那么您将不得不从所有这些视图中删除装饰器(或更糟糕的是,代码)。如果以后要记录视图的性能,则需要将装饰器添加到所有视图。这并不完美,您希望有某种机制来完成所有这些事情,而无需在视图中(或视图的顶部)进行指定。

通常,您可以说它执行在所有个请求-响应周期上执行的任务(尽管中间件软件当然可以检查请求/响应,并决定保持请求/响应不变)。

通过添加许多中间件,但是会减慢请求-响应路径,因此,例如,如果您没有身份验证系统,则抛弃相关的中间件(即使未使用)仍会使用某些中间件可能是有益的循环以确定未使用它。尽管您可以在Django中间件中实现任何Python函数,但一般的中间件可以处理简单常见事物。

Django documentation包含有关开发自己的中间软件的部分。