0

我正在查看来自Django Official Docs的以下代码

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

然后我深入研究了django.http的源代码

class HttpResponse(HttpResponseBase):
    """
    An HTTP response class with a string as content.
    This content can be read, appended to, or replaced.
    """

    streaming = False

    def __init__(self, content=b'', *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Content is a bytestring. See the `content` property methods.
        self.content = content

    def __repr__(self):
        return '<%(cls)s status_code=%(status_code)d%(content_type)s>' % {
            'cls': self.__class__.__name__,
            'status_code': self.status_code,
            'content_type': self._content_type_for_repr,
        }

    def serialize(self):
        """Full HTTP message, including headers, as a bytestring."""
        return self.serialize_headers() + b'\r\n\r\n' + self.content

    __bytes__ = serialize

    @property
    def content(self):
        return b''.join(self._container)

    @content.setter
    def content(self, value):
        # Consume iterators upon assignment to allow repeated iteration.
        if (
            hasattr(value, '__iter__') and
            not isinstance(value, (bytes, memoryview, str))
        ):
            content = b''.join(self.make_bytes(chunk) for chunk in value)
            if hasattr(value, 'close'):
                try:
                    value.close()
                except Exception:
                    pass
        else:
            content = self.make_bytes(value)
        # Create a list of properly encoded bytestrings to support write().
        self._container = [content]

Q1:我们不应该使用return HttpResponse(content=html)因为content是在中定义的关键字参数def __init__(self, content=b'', *args, **kwargs):吗?

Q2:装饰器在哪里@content.setter定义?

Q3:何时何地self._container定义属性?

Q4:命令的一切如何运作return HttpResponse(html)

发现了类似的问题Django的http.response的属性是什么?_container,但我根本不明白答案。

4

1 回答 1

1

Q1:python关键字参数同时接受ordered arguments without keywordunordered arguments with keyword.and关键字参数总是带有默认值。我给你一个例子。

def f(a=0,b=0,c=0):
    pass

f(1,2,3)
f(a=1,b=2,c=3)
f(1,b=2,c=3)
#they call funciton f with same arguments

Q2:@content.setter是一个属性装饰器。它与@property.
如果你不熟悉setterand getter。我给你一个简单的说明:我们可以直接给对象的属性一个值,但是如果我们想要做一些转换或检查,那么我们可以使用属性装饰器。
这是关于属性装饰器的 Python 文档。你可以阅读它。


Q3:对此我不确定。也许有些人可以给出更好的答案。但我想self._container不需要定义。_container会初始化@content.setter,如果_container在初始化之前被调用,它会抛出一个错误,这可能是作者的意图,因为你不能不返回一个不好的初始化HttpResponse。


Q4:如果你真的对它的工作方式感兴趣。return HttpResonse(html)我建议你使用调试模式。在 Visual Studio 代码或 pycharm 或任何其他流行的 IDE 中运行调试模式很容易。
然后您可以逐步运行代码。在每一步中,您都可以调查上下文中的每个变量。相信我,这非常有帮助。我总是使用调试来研究框架。

于 2021-06-23T07:27:33.363 回答