У нас есть приложение react
, связывающееся с django бэкэндом. Когда приложение react
хочет загрузить файл в бэкэнд, мы отправляем запрос формы, в котором одно поле является дескриптором загружаемого файла. Поле получено на стороне Django как InMemoryUploadedFile
, который является объектом с некоторым количеством chunks
, который может быть обработан, например, следующим образом:
def save_uploaded_file(uploaded_file, handle):
"""
Saves the uploaded file using the given file handle.
We walk the chunks to avoid reading the whole file in memory
"""
for chunk in uploaded_file.chunks():
handle.write(chunk)
handle.flush()
logger.debug(f'Saved file {uploaded_file.name} with length {uploaded_file.size}')
Теперь я создаю некоторое тестирование фреймворка с использованием requests
для управления нашим API. Я пытаюсь эмулировать этот механизм, но, как ни странно, requests
настаивает на чтении с открытого дескриптора перед отправкой запроса. Я делаю:
requests.post(url, data, headers=headers, **kwargs)
с:
data = {'content': open('myfile', 'rb'), ...}
Обратите внимание, что я не читаю из файла, я просто открываю его. Но запрос настаивает на чтении с него и отправляет внедренные данные, что имеет несколько проблем:
- может быть огромным
- , будучи двоичными данными, он искажает запрос
- это не то, что ожидает мое приложение
Я не хочу этого: я хочу, чтобы requests
просто "потоковая передача" этого файла, а не читать его. Существует параметр files, но он создаст составную часть с файлом, встроенным в запрос, что опять-таки не то, что я хочу. Я хочу, чтобы все поля данных передавались в запросе, а поле содержимого передавалось. Я знаю, что это возможно, потому что:
- браузер делает это
- Почтальон делает это
- тестовый клиент django делает это
Как заставить запросы направлять определенный файл в данные?