【问题标题】:Tyring to understand WSGI interface in Django试图理解 Django 中的 WSGI 接口
【发布时间】:2020-08-18 10:16:57
【问题描述】:

我最近试图理解什么是 WSGI 应用程序:

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

为了向服务器发送数据,您只需调用 start_response 并返回一个可迭代对象。

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

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

Django 的 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】:

    您看不到传递给 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)
    

    所有这些都展示了如何定义一个可调用对象。可调用对象是如何调用的,这是一段不同的代码,并且无论可调用对象是如何定义的,它看起来都是一样的:

    eight = add5(3)
    

    无论我们构造add5 的哪种方式,您都可以尝试验证此行是否有效。


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

    Django 的get_wsgi_application 函数是一个包装器,它返回一个相同形式的可调用对象:可以给定环境并启动响应。

    如果你想看看它是如何定义的,下面是它的外观:

    get_wsgi_application:

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

    WSGIHandler:

    class WSGIHandler(base.BaseHandler):
        # ...
        def __call__(self, environ, start_response):
            # ...
    

    您会注意到它看起来与我的上一个示例几乎完全相同:构造一个可调用对象的函数。可以使用两个参数调用可调用对象:environstart_response

    在调用方面,不是在您的代码中,而是在 WSGI 容器中(例如 Apache 的mod_wsgi,或者在 gUnicorn...),无论您使用一个简单的函数(如在您的第一个示例中)或可调用对象(如在 Django 中):

    response = application(environ, start_response)
    

    【讨论】:

    • 感谢您深入了解可调用对象。让我明白
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多