Как разобрать составные данные/форму-данные из запроса put в django
Я хочу отправить форму в свой сервер и использовать данные формы в качестве начального значения для моей формы. Простые действия, если вы используете запрос POST:
def intervals(request, **kwargs):
form = MyForm(initial=request.POST)
Однако я отправляю форму, которая должна заменить текущий ресурс, который должен быть идиоматически запросом PUT
(я использую HTMX, который позволяет вам это сделать). Проблема в том, что я не могу понять, как я могу проанализировать данные формы из запроса put. request.PUT
не существует, а QueryDict
работает только для параметров запроса. Что я здесь упускаю?
request.POST
создается с помощью метода:
def _load_post_and_files(self):
"""Populate self._post and self._files if the content-type is a form type"""
if self.method != "POST":
self._post, self._files = (
QueryDict(encoding=self._encoding),
MultiValueDict(),
)
return
if self._read_started and not hasattr(self, "_body"):
self._mark_post_parse_error()
return
if self.content_type == "multipart/form-data":
if hasattr(self, "_body"):
# Use already read data
data = BytesIO(self._body)
else:
data = self
try:
self._post, self._files = self.parse_file_upload(self.META, data)
except (MultiPartParserError, TooManyFilesSent):
# An error occurred while parsing POST data. Since when
# formatting the error the request handler might access
# self.POST, set self._post and self._file to prevent
# attempts to parse POST data again.
self._mark_post_parse_error()
raise
elif self.content_type == "application/x-www-form-urlencoded":
# According to RFC 1866, the "application/x-www-form-urlencoded"
# content type does not have a charset and should be always treated
# as UTF-8.
if self._encoding is not None and self._encoding.lower() != "utf-8":
raise BadRequest(
"HTTP requests with the 'application/x-www-form-urlencoded' "
"content type must be UTF-8 encoded."
)
self._post = QueryDict(self.body, encoding="utf-8")
self._files = MultiValueDict()
else:
self._post, self._files = (
QueryDict(encoding=self._encoding),
MultiValueDict(),
)
так что, по сути, замените это, но тогда без защиты для self.method
:
def load_post_and_files(request):
if request._read_started and not hasattr(request, "_body"):
request._mark_post_parse_error()
return
if request.content_type == "multipart/form-data":
if hasattr(request, "_body"):
# Use already read data
data = BytesIO(request._body)
else:
data = request
try:
return request.parse_file_upload(request.META, data)
except (MultiPartParserError, TooManyFilesSent):
# An error occurred while parsing POST data. Since when
# formatting the error the request handler might access
# request.POST, set request._post and request._file to prevent
# attempts to parse POST data again.
request._mark_post_parse_error()
raise
elif request.content_type == "application/x-www-form-urlencoded":
# According to RFC 1866, the "application/x-www-form-urlencoded"
# content type does not have a charset and should be always treated
# as UTF-8.
if request._encoding is not None and request._encoding.lower() != "utf-8":
raise BadRequest(
"HTTP requests with the 'application/x-www-form-urlencoded' "
"content type must be UTF-8 encoded."
)
return QueryDict(request.body, encoding="utf-8"), MultiValueDict()
else:
return = (
QueryDict(encoding=request._encoding),
MultiValueDict(),
)
и, таким образом, работать с:
def intervals(request, **kwargs):
data, files = load_post_and_files(request)
form = MyForm(initial=request.POST)
Вы также можете использовать Фреймворк Django REST, который выполняет синтаксический анализ для всех HTTP-методов, по существу, переопределяя ._load_post_and_files()
метод, а затем вызовите метод с именем ._parse(..)
.