Django解决无法从request.POST中获取URL传进来的参数
作者:Similar_Fair
这篇文章主要介绍了Django解决无法从request.POST中获取URL传进来的参数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
背景
上周做项目的时候,有个Post Webhook回调不仅在Body里传了数据,同时URL里也传了参数。
request.POST这个QueryDict打印出来的值为{},无法获取URL中的参数。
原因分析
这种问题,首先就是看代码。
大概扫了下Request的代码,问题出在如下的位置:
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: # 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': self._post, self._files = QueryDict(self.body, encoding=self._encoding), MultiValueDict() else: self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict()
这个回调接口传进来的content_type 为 application/xml,所以会默认不解析。
其实按照这段代码来看,只要是Post请求,都不会解析URL上的参数(我觉得这才是正常套路,接口回调不规范,他们要背锅)。
问题解决
其实很简单,我们只需要把带参数的URL搞出来即可。
post = QueryDict(request.get_full_path().split('?')[1]) post.get('xx')
或者
# 这段代码是根据get_full_path的具体实现写出来的,还没测,提供个思路给大家 post = QueryDict(iri_to_uri(self.META.get('QUERY_STRING', ''))) post.get('xx')
get_full_path具体实现如下:
def get_full_path(self, force_append_slash=False): return self._get_full_path(self.path, force_append_slash) def _get_full_path(self, path, force_append_slash): # RFC 3986 requires query string arguments to be in the ASCII range. # Rather than crash if this doesn't happen, we encode defensively. return '%s%s%s' % ( escape_uri_path(path), '/' if force_append_slash and not path.endswith('/') else '', ('?' + iri_to_uri(self.META.get('QUERY_STRING', ''))) if self.META.get('QUERY_STRING', '') else '' )
(遇事不决,看代码就对了)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。