Python Django URL路由中命名参数与位置参数的区别
在我的应用程序中,我有以下的URL路由设置:
urls.py
urlpatterns = patterns('rocflavors.views',
url('^detail/(?P<content_type>[^/]+)/(?P<slug>[^/]+)/(?P<asset_id>\d{1,32})$', 'flavors_detail', name='flavors_detail'),
)
views.py
def flavors_detail(request, slug, asset_id, content_type, format="html"):
看起来我使用的参数是命名参数(content_type, slug, asset_id)。
那么,Django/Python是怎么知道什么时候传递位置参数和关键字参数的呢?
flavors_detail
这个函数接受5个参数,但在URL中它们的顺序是乱的。
1 个回答
2
为了回答你的问题,flavor_detail
这个函数会接受四个参数(按顺序)和一个关键字参数。url
中的正则表达式会按顺序传递它找到的匹配项,但因为你为每个参数都定义了关键字,所以它会传递一个 kwarg
字典。由于你保持了变量名的一致性,这个 dict
会把正确的参数放在正确的位置(如果你使用了不同的变量名,这样就不行了)。你可以通过下面描述的方式,简单地指定关键字参数来避免这种“魔法”。
你的 url
是一个定义它们的正则表达式:
?P<content_type>
这将生成 kwarg
content_type
。可以查看 Python 中的 re
模块(文档)。
(?P<name>...)
类似于普通的括号,但通过符号组名 name,可以在正则表达式的其他部分访问该组匹配的子字符串。组名必须是有效的 Python 标识符,并且每个组名在正则表达式中只能定义一次。符号组也是一个编号组,就像没有命名的组一样。因此,下面示例中名为 id 的组也可以作为编号组 1 来引用。
由于你将变量定义为关键字参数 kwargs
,你可以更改你的视图声明以接受关键字参数:
def flavors_detail(request, slug=slug, asset_id=asset_id, content_type=content_type, format="html"):
不过,Python 也会接受你之前的定义(我之前的评论有点早),只要你小心保持参数的顺序!关于这个过程还有更多信息,可以在这里找到 这里 - 引用如下:
如果存在关键字参数,它们会首先被转换为位置参数。