背景(但不是仅限 Django 的问题)是 Django 测试服务器不会在其响应和请求 URL 中返回方案或 netloc。
例如,我得到了/foo/bar
,并且我希望以 结束http://localhost:8000/foo/bar
。
urllib.parse.urlparse
(但并没有那么复杂urllib.parse.urlsplit
)使得从测试 URL 和我已知的服务器地址收集相关信息变得容易。看起来比必要更复杂的是,通过urllib.parse.urlcompose添加 scheme 和 netloc 来重新组合一个新的 URL ,这个 URL 需要位置参数,但没有文档说明它们是什么,也不支持命名参数。同时,解析函数返回的是不可变的元组……
def urlunparse(components):
"""Put a parsed URL back together again. This may result in a ..."""
我确实让它工作了,请参阅下面的代码,但它看起来真的很笨拙,围绕我需要首先将解析元组转换为列表,然后在所需的索引位置修改列表的部分。
有没有更 Pythonic 的方式?
示例代码:
from urllib.parse import urlsplit, parse_qs, urlunparse, urlparse, urlencode, ParseResult, SplitResult
server_at_ = "http://localhost:8000"
url_in = "/foo/bar" # this comes from Django test framework I want to change this to "http://localhost:8000/foo/bar"
from_server = urlparse(server_at_)
print(" scheme and netloc from server:",from_server)
print(f"{url_in=}")
from_urlparse = urlparse(url_in)
print(" missing scheme and netloc:",from_urlparse)
#this works
print("I can rebuild it unchanged :",urlunparse(from_urlparse))
#however, using the modern urlsplit doesnt work (I didn't know about urlunsplit when asking)
try:
print("using urlsplit", urlunparse(urlsplit(url_in)))
#pragma: no cover pylint: disable=unused-variable
except (Exception,) as e:
print("no luck with urlsplit though:", e)
#let's modify the urlparse results to add the scheme and netloc
try:
from_urlparse.scheme = from_server.scheme
from_urlparse.netloc = from_server.netloc
new_url = urlunparse(from_urlparse)
except (Exception,) as e:
print("can't modify tuples:", e)
# UGGGH, this works, but is there a better way?
parts = [v for v in from_urlparse]
parts[0] = from_server.scheme
parts[1] = from_server.netloc
print("finally:",urlunparse(parts))
示例输出:
scheme and netloc from server: ParseResult(scheme='http', netloc='localhost:8000', path='', params='', query='', fragment='')
url_in='/foo/bar'
missing scheme and netloc: ParseResult(scheme='', netloc='', path='/foo/bar', params='', query='', fragment='')
I can rebuild it unchanged : /foo/bar
no luck with urlsplit though: not enough values to unpack (expected 7, got 6)
can't modify tuples: can't set attribute
finally: http://localhost:8000/foo/bar