在 Django Urls 中将 URL 作为参数传递
Posted
技术标签:
【中文标题】在 Django Urls 中将 URL 作为参数传递【英文标题】:Pass a URL as parameter in Django Urls 【发布时间】:2019-02-10 19:33:26 【问题描述】:我正在开发一个 Django(2) 项目,我需要在 Django URL 中将 URL 作为参数传递, 这是我尝试过的:
urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api/(?P<address>.*)/$', PerformImgSegmentation.as_view()),
]
views.py:
class PerformImgSegmentation(generics.ListAPIView):
def get(self, request, *args, **kwargs):
img_url = self.kwargs.get('address')
print(img_url)
print('get request')
return 'Done'
但它不起作用,我通过邮递员传递了一个名为address
的参数,但它失败了。
它返回此错误:
未找到:/api/ [05/Sep/2018 15:28:06]“GET /api/HTTP/1.1”404 2085
【问题讨论】:
您尝试通过但失败的 URL 示例是什么? 这里是:https://i.imgur.com/TGJHFe1.jpg
没有。您必须准确告诉我包含外国地址的您网站的地址是什么样的,因为您显示的错误消息是针对/api/
的请愿书,后面没有地址(例如/api/http://www.google.com/
,这是为了什么你不应该匹配任何东西。
我也没有信心,但我认为您不应该将url
与path
混为一谈。在 Django 2 中,我认为您应该始终使用后者。
【参考方案1】:
Django 2.0 及更高版本现在使用 path
func 构造函数来指定 URL。我不确定是否仍然向后兼容;你可以用一个简单的例子来试试。但是,如果您开始编写应用程序,您应该使用path
:
path('api/<str:encoded_url>/', view_action)
为避免与在您的应用中查看的标准路径混淆,我不建议使用path
转换器而不是str
(前者可以匹配/
,而另一个不能)。
您可以通过此article 获得更多关于从url
转换为path
的帮助。
第二步,获取encoded_url
作为视图中的参数。您需要对其进行解码:要在 get url 中传递一个 url,您可以使用 ASCII 编码来替换某些保留字符(例如,正斜杠)。
您可以使用urllib
轻松编码和解码网址(还有其他模块)。对于 Python 3.7 语法如下(docs here)
>>> urllib.parse.quote("http://www.google.com")
'http%3A//www.google.com'
>>> urllib.parse.unquote('http%3A//www.google.com')
'http://www.google.com'
请记住:如果您在不引用的情况下传递 url,它将不匹配:您不接受与该路径表达式的斜杠匹配。 (编辑:quote 方法默认不转换正斜杠,为此您需要传递:quote(<str>, safe='')
例如,您的 GET 调用应该是:/api/http%3A%2F%2Fwww.google.com
。但是,最好将 URL 作为 get 参数传递,并且在路径中只关心可读性(例如 /api/name_to_my_method?url=http%3A%2F%2Fwww.google.com
)。路径工程对于可读性很重要,并且通过引用的 URL 通常不是最佳实践(尽管完全可能)。
【讨论】:
嗨@J.C.Rocamonde,我尝试了path
方法来定义我的URL,然后以http://127.0.0.1:8000/api?url=https://i.imgur.com/TGJHFe1.jpg
发送请求,但它返回404 not found
错误。
因为 1) GET 参数不是 URL 方案的一部分,这些是由服务器处理的。所以你的请求是'/api'(不匹配)。即使您按照我告诉您的操作而不对 URL 进行编码,您也会得到 404,因为它与斜杠不匹配。此外,您正在发送一个 GET 参数,因此您必须从会话中获取它。
我真的不鼓励你不要对 URL 进行编码。路径匹配是如果你想进行复杂的路径匹配,而不是传递 url。如果您稍后有其他更复杂的 api 路径定义,则会导致冲突。对 URL 进行编码是标准做法。【参考方案2】:
Django 2.0 提供了Path Converters
来将路径参数转换为适当的类型,其中还包括一个urls
的转换器,看看docs。
所以,您的网址可以是这样的:
path('api/<path:encoded_url>/', PerformImgSegmentation.as_view()),
因此,path
转换器将匹配任何非空字符串,包括路径分隔符“/”。这允许您匹配完整的 URL 路径,而不是像 str 那样仅匹配 URL 路径的一部分。
然后在视图中,我们可以简单地从 kwargs
获取我们的 URL
值,如下所示:
img_url = self.kwargs.get('encoded_url')
print(img_url)
【讨论】:
没有。你绝对不应该那样做。永远不要匹配 api URL 方案中的路径。那会引起冲突。我跟你说的没问题。老实说,您有没有费心阅读我的答案并通过 cmets 与之交互?提出问题并在获得答案时发布您自己的答案以及我告诉您的完全相同的建议是没有意义的(嗯,实际上不是,因为您不应该在那里使用path
。
此外,没有特定类型的 URL 转换器。我提供给您的链接中显示了转换器。那是错的。如果您愿意,所有转换器都用于 URL,因为转换器用于在 Django 中使用 with URL 方案,并用于传递编码的 URL,应将其视为纯数据。一个字符串。除了路径匹配之外,您还有整数和 UUID 代码。
你通常要先使用这两个。第三是针对特定需求,最后是如果您知道自己在做什么。 Django 有一个非常好的路径方案生成器。我不明白为什么初学者会用整个路径匹配来解析自己的 URL。
嗨@J.C.Rocamonde,我已仔细阅读您的答案并尝试了该解决方案,但它对我不起作用,我已经发布了对我有用的内容。
答案中存在错误,您是对的,但您只需要回复并告诉我。这并没有使匹配斜线的做法更好(你不应该)【参考方案3】:
您是否尝试将 url https://i.imgur.com/TGJHFe1.jpg
作为参数从 django 模板传递给视图?
您可以简单地在应用的 url.py 中编写:
path(api/<path:the_url_you_want_to_pass>', PerformImgSegmentation.as_view())
请看看这个article。
【讨论】:
以上是关于在 Django Urls 中将 URL 作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django 2 中将 url 中的 # 作为参数传递