Django: 路由与视图 互动版

子路由命名空间

当我们使用reverse()函数为指定名称的路由项反向生成URL时,有可能会 碰到一种情况:在不同的路由表中使用了相同的名称。

例如,你为你的报表子系统中的首页视图路由项起名字r_index

urlpatterns = [
    url(r'^$',v_report_index,name='r_index'),
    url(r'^income/([0-9]{4})/$',v_report_income_year,name='r_income_year'),
    url(r'^income/([0-9]{4})/([0-9]{2})/$',v_report_income_month,name='r_income_month'),
]

而你的同事也为他的邮箱子系统中的首页视图路由项命名为r_index

urlpatterns = [
    url(r'^$',v_mail_index,name='r_index'),
    url(r'^inbox/$',v_mail_inbox,name='r_inbox'),
    url(r'^outbox',v_mail_outbox,name='r_outbox'),
]

那么,现在reverse('r_index')生成哪个URL才算正确?

当然,我们可以要求各个子系统在给路由项命名时使用统一分配的前缀 以避免冲突。比如,将报表子系统中的路由项命名为report.r_index, 而将邮件子系统中的路由项命名为email.r_index,但这种语法之外 的约定相当脆弱,非常容易崩溃。

Django的解决方案是给子路由表分配命名空间(namespace)

当调用include()函数引入一个子路由表时,使用namespace关键字参数 可以为其分配一个命名空间:

urlpatterns = [
    url(r'^$',v_index),
    url(r'^report/',include(report_urlpatterns,namespace='report')),
    url(r'^email/',include(mail_urlpatterns,namespace='email')),
]

一旦子路由表被分配了命名空间,它的路由项名称就自动被附加了命名空间前缀。 现在,报表子系统中的路由项r_index全名变成了report:r_index,而邮件 子系统中的路由项r_index全名变成了email:r_index

现在不会错了:

print reverse('report:r_index')
print reverse('email:r_index')
思考一下,如果修改了子路由的命名空间,是否需要所有指向这个子路由表 中URL的reverse()调用?