Django视图–URL调度器
1。Django处理请求
Django依次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来,如:
from django.urls import path
form . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/, views.article_detail')
]
# 请求/articles/2005/03/与列表中的第三个条目匹配。Django会调用该函数 views.month_archive(request, year=2005, month=3)
# /articles/2003/将匹配列表中的第一个模式,而不是第二个模式,因为模式是按顺序测试的,第一个是第一个要通过的测试。随意利用订单插入这样的特殊情况。在这里,Django会调用该函数 views.special_case_2003(request)
# /articles/2003 不匹配任何这些模式,因为每个模式都要求URL以斜杠结尾。
# /articles/2003/03/building-a-django-site/将匹配最终模式。Django会调用该函数 。views.article_detail(request, year=2003, month=3, slug="building-a-django-site")
- 要从 url 捕获值,需使用尖括号
- 捕获的值可以选择包括转换器类型。例如,用于
<int:name>
捕获整数参数。如果未包含转换器,则匹配除/
之外的任何字符串。
2.路径转换器
- str - 匹配除路径分隔符
/
之外的任何非空字符串。如果转换器未包含在表达式中,则这是默认值 - int - 匹配零或任何正整数。放回一个 int。
- slug - 匹配由 ASCII 字母或数字组成的任何 slug 字符串,已经连字符如下划线。例如:
building-your-1st-django-site
。 - uuid - 匹配格式化的 UUID 。为了防止多个 URL 隐射到同一页面,必须包含短划线,并且字母必须小写,例如
075194d3-6885-417e-a8a8-6c931e272f00
。返回一个UUID
实例。 - path
- 匹配任何非空字符串,包括路径分隔符
’/'。这允许您匹配完整的URL路径,而不仅仅是URL路径的一部分
str`。
3. 使用 include() 包含其他的URLconf
# 每当Django遇到时include(),它都会删除与该点匹配的URL的任何部分,并将剩余的字符串发送到包含的URLconf以进行进一步处理。
from django.urls import include, path
from apps.main import views as main_views
from credit import views as credit_views
extra_patterns = [
path('reports/', credit_views.report),
path('reports/<int:id>', credit_views.report),
path('charge', credit_views.charge),
]
# 在这个例子中,/credit/reports/ 将被credit_views.report()这个视图处理
urlpatterns = [
path('', main_views.homepage),
path('help/', include('apps.help.urls')),
path('credit', include(extra_patterns)),
]
# 在下面的例子中,主页捕获的"username"变量将被如期传递给包括 views.blog.index 指向的URL配置。
# In settings/urls/main.py
from django.urls import include, path
urlpatterns = [
path('<username>/blog/', include('foo.urls.blog')),
]
# In foo/urls/blog.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.blog.index),
path('archive/', views.blog.archive),
]
4. 传递额外的参数
from django.urls import path
from . import views
urlpatterns = [
path('blog/<int:year>', views.year_archive, {'foo': 'bar'})
]
在这个例子中,对于请求 /blog/2005/ ,将调用 views.year_achive(request, year=2005, foo=bar)
- 处理冲突:如果使用URL模式捕获命名关键字参数,并在其额外参数字典中传递具有相同名称的参数。发生这种情况时,将使用字典中的参数而不是URL中捕获的参数。
5. URL的反向解析
Django提供了用于执行URL反转的工具,这些工具匹配需要URL的不同层:
- 在模板中:使用
url
模板标记。 - 在Python代码中:使用该
reverse()
函数。 - 在与处理Django模型实例的URL相关的更高级代码中:该
get_absolute_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' 2012 %}">2012 Archive</a>
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
from django.http import HttpResponseRedic
from django.urls import reverse
def redirect_to_year(request):
year = 2006
return HttpResponseRedirect(reverse('news-year-archive, args=(year, )'))
6. URL命名空间
# 第一种
# polls/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]
# urls.py
urlpatterns = [
path('polls/', include('polls.urls')),
]
# 第二种
from django.urls import include, path
from . import views
polls_patterns = ([
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
], polls)
urlpatterns = [
path('polls/', include(polls_patterns)),
]