子路由命名空间
当我们使用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()调用?