I was looking into below codes from 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)
Then I deep dive into the source code of 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: Shouldn't we use return HttpResponse(content=html)
since content
is a keyword argument defined in def __init__(self, content=b'', *args, **kwargs):
?
Q2: Where is the decorator @content.setter
defined?
Q3: when & where the attribute self._container
is defined?
Q4: How everything works out for command return HttpResponse(html)
?
Found similar question What is the _container
property of Django's http.response?, but I did not understand the answer at all.
Q1: python keyword argument accept both ordered arguments without keyword
and unordered arguments with keyword
.and keyword arguments always come with default values.I will give you an example.
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
is a property decorator.it make effect togather with @property
.
if you don't familiar with setter
and getter
.I give your a brief:We can direct give object's property a value directly,but if we want do some tranform or check,then we can use property decorator.
here is Python doc about property decorator.you can read it.
Q3:I am not sure about this.maybe some can give better answer.but I guess self._container
do not need define._container
will init by @content.setter
,and if the _container
be called before init,it will throw an error,that maybe the author's intent because you can't not return an not well init HttpResponse.
Q4:If you really interest in how the return HttpResonse(html)
work.I suggest you use debug mode.it's easy to run debug mode in visual studio code or pycharm or any other popular IDE.
then you can run code step by step.at each step you can investigate every variable in the context.trust me that's very helpful.I always use debug to study framework.