尝试理解Django中的WSGI接口

问题描述 投票:0回答:1

我最近试图弄清什么是WSGI应用程序:

WSGI应用程序只是一个传递给环境的可调用对象 -包含请求数据的字典,以及调用start_response函数以开始发送响应的字典。

为了将数据发送到服务器,您所要做的就是调用 start_response并返回一个可迭代的对象。

所以,这是一个简单的应用程序:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ['Hello World!']

[Djangos wsgi.py是

"""
WSGI config for basic_django project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""
import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'basic_django.settings')

application = get_wsgi_application()

但是当我看到wsgi.py时,application = get_wsgi_application()可调用项没有与environstart_response函数一起传递

所以如何理解这一点

django wsgi
1个回答
1
投票
您看不到传递给application的内容-这是WSGI容器的工作,而不是您的工作。您要

定义 application作为可以通过这两个参数的东西。

有多种方法可以使之可通话。最简单的是一个函数:

def add5(x): return x + 5

另一个是匿名函数或lambda:

add5 = lambda x: x + 5

还有另一个是具有__call__方法的类的对象:

class AdderOf5: def __call__(self, x): return x + 5 add5 = AdderOf5()

而且您可以将其中任何一个包装到返回可调用对象的函数中:

def make_add_y(y): def add_y(x): return x + y return add_y add5 = make_add_y(5)

def make_add_y(y): return lambda x: x + y add5 = make_add_y(5)

第三个选项不需要包装,因为该类已经是工厂了:

class AdderOfY: def __init__(self, y): self.y = y def __call__(self, x): return x + self.y add5 = AdderOfY(5)

而且我想我们甚至可以创建一个构造可调用对象并将其返回给我们的函数:

class AdderOfY: def __init__(self, y): self.y = y def __call__(self, x): return x + self.y def make_adder(y): return AdderOfY(5) add5 = make_adder(5)

所有这些都显示了如何

定义

可调用对象。 invoked的可调用方式是另一段代码,并且看起来是相同的,无论可调用的定义方式如何:eight = add5(3)
您可以尝试验证此行是否可用,无论我们构建add5的方式如何。


返回WSGI:您提供的示例创建了一个接受两个参数的简单函数。

Django的get_wsgi_application函数是一个包装器,该包装器返回具有相同形式的可调用对象:可以为该对象提供环境并启动响应。

如果您想查看它的定义,请看它的外观:

get_wsgi_application

get_wsgi_application

def get_wsgi_application():
    # ...
    return WSGIHandler()

WSGIHandler

您会注意到它看起来与我的上一个示例几乎完全相同:一个构造可调用对象的函数。可以使用两个参数来调用可调用对象:WSGIHandlerclass WSGIHandler(base.BaseHandler):
    # ...
    def __call__(self, environ, start_response):
        # ...

在调用方面,在代码中是

not

,但在WSGI容器中(例如Apache的environ或gUnicorn ...中),无论您使用的是简单函数,都看起来像这样(例如您的第一个示例)或可调用对象(例如Django):start_response
© www.soinside.com 2019 - 2024. All rights reserved.