Django 中 app_name (应用命名空间) 和 namespace (实例命名空间) 的区别

首先来看官方文档

  • 应用命名空间
    它表示正在部署的应用的名称。一个应用的每个实例具有相同的应用命名空间。例如,可以预见Django 的管理站点的应用命名空间是'admin'。
  • 实例命名空间
    它表示应用的一个特定的实例。实例的命名空间在你的全部项目中应该是唯一的。但是,一个实例的命名空间可以和应用的命名空间相同。它用于表示一个应用的默认实例。例如,Django 管理站点实例具有一个默认的实例命名空间'admin'。
    URL 的命名空间使用':' 操作符指定。例如,管理站点应用的主页使用'admin:index'。它表示'admin' 的一个命名空间和'index' 的一个命名URL。

官方文档这一段写的有点晦涩。你如果看懂了,那就意味着可以关闭本页面。
看不懂的话还是直接上代码说明吧~
app_name比较简单,文档说的已经很清楚了。着重说namespace.
我们只讨论两个命名空间取值不同的情况。
先上代码

#urls.py

from django.conf.urls import include, url
urlpatterns = [
    url(r'^author-polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
    url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls', app_name='polls')),
]
#polls/urls.py

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
    ...
]

假设我们使用Django开发了一个投票网站,那么应该有一套展示给投票者的页面(author-polls)和一套管理员的页面(publisher-polls)我们在项目的urls.py中设置好了路由,关于投票(poll)的路由全部转发到polls/urls.py中去,但是因为需要管理员和投票者两套页面,如果直接按照每页面单独写一个url路由的话,本套程序需要4条(2张主页两张投票/管理页),不符合代码复用的原则。
如果我们想要代码复用,那就需要namespace(实例命名空间)
实例命名空间就是我们当前正在访问的对象的命名空间。比如我们正在访问管理员的主页那么我的实例命名空间就是publisher-polls,以投票者身份访问主页则是author-polls

现在假设我们在代码中这样调用:

#在基于类的视图的方法中:
reverse('polls:index', current_app=self.request.resolver_match.namespace)
#在模板中:
{% url 'polls:index' %}

因为无论是投票者还是管理员访问本网站,在Django层面我们访问的都是polls应用,即app_name是polls所以根据访问角色的页面就出现了两种情况。
投票者访问时:namespace 是 author-polls
管理员访问时:namespace 是 publisher-polls
此时我们的Django调用以上相同的代码回产生不同的结果
投票者访问
访问 index 页面 —— 'polls:index' 将解析成'author-polls' 实例的主页面
管理员访问
访问 index 页面 —— 'polls:index' 将解析成'publisher-polls' 实例的主页面
detail 页面同上
这样就实现了,自动根据访问角色不同,返回不同页面的效果,而poll应用下的路由配置代码只需要写一遍。

推荐阅读更多精彩内容