I can't find one good source that actually tries to explain it. The top 5 search results are just different links to source code. Right now, I'm trying to read a PDF that is being returned from a GET
request, and I want to know why it's in response._container
, when response is type HttpResponse
. Is this PDF even what I'm looking for? Why is it the second element in the _container
list?

- 571
- 2
- 4
- 22
-
a list of properly encoded bytestrings to support `write()` – JPG Mar 10 '20 at 12:25
1 Answers
Firts point, this is not a "property" but an "attribute" - in Python, "property" is a builtin type implementing generic computed attribute support, and HttpResponse._container
is actually used as implementation support for the HttpResponse.content
property.
So this an implementation detail (as you can tell by the single leading underscore), and hence not documented indeed (a package or framework's documentation only concerns the API, not the implementation). IOW, the best documentation here is the source code. FWIW, the source code is always the ultimate documentation, even if not always the most user-friendly ;-)
Hopefully, this part is quite easy to understand (code from the current master branch, but this part is quite stable):
https://github.com/django/django/blob/master/django/http/response.py#L308
class HttpResponse(HttpResponseBase):
# ....
@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, 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]
def __iter__(self):
return iter(self._container)
def write(self, content):
self._container.append(self.make_bytes(content))
# ...
def writelines(self, lines):
for line in lines:
self.write(line)
As you can see, the response's content is exposed as the (read/write) content
property, but is actually stored in the _container
attribute. This is used to 1/ make sure the content is stored in the expected format, 2/ allow support for the response.write()
and iter(response)
operations.
Two points bout the use of a list here:
1/ using a list to dynamically build strings is a pretty common Python idiom - adding to a list and joining it in the end is usually faster than concatenating strings
2/ this also allow to make the HttpResponse
object a "file-like" object - HttpResponse has similar close
, write
, writelines
, flush
, tell
and __iter__
operations.
Why is it the second element in the _container list?
Probably because it's been written as the second element.

- 75,974
- 6
- 88
- 118