【问题标题】:content function in django.http source codedjango.http 源码中的内容函数
【发布时间】:2021-09-06 14:48:53
【问题描述】:

我正在查看来自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)的一切如何?

找到了类似的问题What is the _container property of Django's http.response?,但是我完全没看懂答案。

【问题讨论】:

    标签: django django-request


    【解决方案1】:

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

    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一起生效。
    如果你对settergetter不熟悉。我给你一个简单的说明:我们可以直接给对象的属性一个值,但是如果我们想要做一些转换或检查,那么我们可以使用属性装饰器。
    这里是Python doc about property decorator。你可以阅读。


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


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

    【讨论】:

    • 在对property()property decorator 进行大量阅读和研究之后,终于从里到外地理解它,现在更适应它了。将按照您的建议使用 PDB 调试并找出 Q4。我选择 PDB 是因为我正在远程调试云中运行的 Django 项目。
    猜你喜欢
    • 1970-01-01
    • 2021-08-25
    • 2012-04-30
    • 2012-01-26
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 2021-09-28
    相关资源
    最近更新 更多