Python Django URL路由中命名参数与位置参数的区别

1 投票
1 回答
2150 浏览
提问于 2025-04-17 19:39

在我的应用程序中,我有以下的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 也会接受你之前的定义(我之前的评论有点早),只要你小心保持参数的顺序!关于这个过程还有更多信息,可以在这里找到 这里 - 引用如下:

如果存在关键字参数,它们会首先被转换为位置参数。

撰写回答