Во-первых, это не «свойство», а «атрибут» - в Python «свойство» является встроенным типом, реализующим поддержку обобщенного c вычисляемого атрибута и HttpResponse._container
фактически используется в качестве поддержки реализации для свойства HttpResponse.content
.
Так что это подробности реализации (как вы можете заметить по единственному нижнему подчеркиванию), и, следовательно, действительно не документировано (документация пакета или инфраструктуры касается только API, а не реализация). Итак, лучшая документация здесь - это исходный код. FWIW, исходный код всегда является окончательной документацией, даже если не всегда самым удобным для пользователя; -)
Надеюсь, эта часть довольно проста для понимания (код из текущей ветки master, но эта часть довольно стабильно):
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)
Как видите, содержимое ответа отображается как свойство (чтение / запись) content
, но на самом деле хранится в атрибуте _container
. Это используется для того, чтобы 1 / убедиться, что содержимое сохранено в ожидаемом формате, 2 / разрешить поддержку операций response.write()
и iter(response)
.
Две точки об использовании списка здесь:
1 / использование списка для динамического построения строк - довольно распространенная идиома Python - добавление в список и присоединение к нему в конце обычно быстрее, чем объединение строк
2 / это также позволяет сделать объект HttpResponse
«файловым» объектом - HttpResponse имеет аналогичные close
, write
, writelines
, flush
, tell
и __iter__
операций.
Почему это второй элемент в списке _container?
Возможно, потому что он записан как второй элемент.