反向解析URL
现在的urlconf是这么配置的
path('post/<int:pk>/', views.some_view),
如果需要将urlconf中的表达式改成entry/<int:pk>
, 必须修改对应的herf属性值, 去项目里把post/
都改成 entry/
显然是不现实的.
Django提供了一个解决这个问题的方案, 只需在URL中提供一个name参数, 并赋值一个你自定义的字符串.
通过这个name参数, 可以反向解析URL, 反向URL匹配, 反向URL查询或者简单的URL反查
from django.urls import path
from . import views
urlpatterns = [
path('articles/<int:year>/', views.year_archive, name='news-year-archive'),
]
可以在模板的代码中使用下面的方法获得它们
<a href="{% url 'news-year-archive' 2020 %}">Year</a>
在视图中可以使用
from django.http import HttpResponseRedirect
from django.urls import reverse
def redirect_to_year(request):
year = 2020
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
应用命名空间app_name
如果 appA, 有一条路由A, 它的name叫做 ‘index’
如果 appB, 有一条路由B, 它的name也叫做 ‘index’
在某个视图中使用reverse('index', args=(..))
, 这样不能确定最终生成的URL到底是路由A还是路由B.
Django提供了一个叫做app_name的属性, 帮我们解决这个问题
from django.urls import path
from . import views
app_name = 'blog_name'
urlpatterns = [
...
]
这样在使用的时候添加上app_name就可以了.
# 视图中
reverse('blog_name:index', args=(...))
# 模板中
{% url 'blog_name:index' %}
实例命名空间namespace
有一个app, 实现一个index页面展示功能 :
- 假设访问Django服务器的人分两类, author和publisher
- 他们都需要访问app
- 需求 : 为两类人实现不同的权限或者页面内容
实现 :
- 根据不同的url来区分两类人, author访问author/....
, publisher访问publisher/...
- 两个url都指向同一个app的url: include('app.urls')
- 在视图中, 根据来访人员的不同, if/else判断, 实现不同的业务逻辑
根urls.py
from django.urls import path, include
urlpatterns = [
path('author/', include('app.urls', namespace='author')),
path('publisher/' include('app.urls', namespace='publisher')),
]
app/urls.py
from django.urls import path
from . import views
app_name = 'app'
urlpatterns = [
path('index/', views.index, name='index'),
path('detail/', views.index, name='detail'),
]
app/views.py
from django.shortcuts import render,HttpResponse
def index(request):
return HttpResponse('当前的命名空间是%s' % request.resolver_match.namespace)
def detail(request):
if request.resolver_match.namespace == 'author':
return HttpResponse('这里是作者页面')
elif request.resolver_mathc.namespace === 'publisher':
return HttpResponse('这里是出版社页面')
else:
return HttpResponse('........')