Django路由URL控制详解

在Django中,URL是Web服务的入口,用户通过浏览器发送的请求都传递到特定的URL地址,然后得到相应。在Django项目中,编写路由即公开接收哪些URL请求,而不在路由中定义的URL将不会被处理或返回。简而言之,URL路由可以被视为Web服务对外公开的API。Django遵循DRY原则,提倡使用简洁而优雅的URL。

图片[1]-Django路由URL控制详解-山海云端论坛

概述

设计应用程序的URL时,可以创建一个称为URLconf(URL配置)的Python模块。这个模块是纯Python代码,负责将URL路径与Python函数(即视图)进行映射。这种映射可以根据需要缩短或延伸,也可以引用其他映射。由于是纯Python代码,因此可以进行动态构造。Django还提供了根据活动语言翻译URL的方法。

如何处理请求

当用户请求页面时,Django根据以下逻辑执行操作:

  1. 决定要使用的根URLconf模块,通常是由ROOT_URLCONF设置的值决定,但如果HttpRequest对象具有urlconf属性(由中间件设置),则将使用该值代替ROOT_URLCONF设置。
  2. 加载该模块并查找可用的urlpatterns,即django.conf.urls.url()实例的列表。
  3. 依次匹配每个URL模式,停在与请求的URL相匹配的第一个模式处。URL匹配是从上到下的短路操作,因此URL在列表中的位置非常关键。
  4. 导入并调用与匹配行中给定的视图相对应的函数。视图是一个简单的Python函数(称为视图函数)或基于类的视图。视图将接收HttpRequest实例以及匹配的正则表达式返回的值作为参数。
  5. 如果没有匹配到正则表达式,或者在过程中出现异常,则调用适当的错误处理视图。

转换器

path转换器

在Django 2.0及以上版本中,默认使用path转换器,示例如下:

from django.urls import path from . 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), ]

注意:

  • 使用尖括号捕获URL中的值,而不是圆括号。
  • 可以使用转换器指定捕获值的类型,例如<int:year>
  • 默认情况下,捕获的结果保存为字符串类型。

re_path转换器(旧版的url)

Django 2.0的url配置改为了path方法,但为了向后兼容,可以使用re_path方法代替path方法:

from django.urls import path, re_path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail), ]

与path方法不同之处在于:

  • 使用正则表达式进行匹配。
  • 所有传递给视图的参数都是字符串类型。

有名分组

使用命名的正则表达式组进行匹配,将捕获的值作为关键字参数传递给视图函数:

from django.urls import path, re_path from app01 import views urlpatterns = [ re_path(r'^articles/2003/$', views.special_case_2003), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ]

路由分发

通常,每个应用程序都会创建一个urls.py路由模块,然后从根路由转发到相应的urls.py模块。路由转发可以使用include()方法,也可以使用url()实例的列表。

from django.conf.urls import include, url urlpatterns = [ # ... 省略 ... re_path(r'^community/', include('django_website.aggregator.urls')), re_path(r'^contact/', include('django_website.contact.urls')), # ... 省略 ... ]

反向解析

在Django项目中,常见的需求是获取URL的最终形式,用于嵌入生成的内容或服务器端导航。Django提供不同的工具用于URL反解:

在模板中使用url模板标签:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

在Python代码中使用reverse()函数:

from django.urls import reverse from django.http import HttpResponseRedirect def redirect_to_year(request): year = 2006 return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

名称空间

为了避免URL命名冲突,可以使用命名空间。在项目的urls.py中,通过include()方法指定命名空间,然后在各个应用的urls.py中定义命名空间。

urlpatterns = [ re_path(r'^app01/', include("app01.urls", namespace="app01")), re_path(r'^app02/', include("app02.urls", namespace="app02")), ]

以上是对Django路由控制URL的详细解释,希望能帮助理解和使用Django中的URL路由机制。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容