Django-路由系统
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。
django2路由配置官方文档
Django1.X 和Django2.X函数对比
| 1.X | 2.0 | 备注 |
|---|---|---|
| - | django.urls.path | 新增,url的增强版 |
| django.conf.urls.include | django.urls.include | 路径变更 |
| django.conf.urls.url | django.urls.re_path | 异名同功能,url不会立即废弃 |
简单的路由配置
path基本示例
这是一个简单的例子:
''' 基本格式: urlpatterns = [ path(route, views视图函数,参数,别名), ] ''' from django.urls import path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), ]
参数说明
- 正则表达式:一个正则表达式字符串
- views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
- 参数:可选的要传递给视图函数的默认参数(字典形式)
- 别名:一个可选的name参数
re_path简单示例示例
''' 基本格式: urlpatterns = [ re_path(正则表达式, views视图函数,参数,别名), ] ''' 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/([0-9]{4})/$', views.year_archive), re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
path和re_path参数捕获方式
path捕获参数的方式
from django.urls import path from . import views urlpatterns = [ path('blog/article/<int:id>/', views.article, name = 'article'), ]
path是通过<>符号来捕获参数的,规则可以理解为:<转换器:变量名>。转换器为传入参数的类型,源文档写得是 Path converters(转换器),django默认支持的转换器有5个:
- str,匹配除了路径分隔符(
/)之外的非空字符串,这是默认的形式 - int,匹配正整数,包含0。
- slug,匹配字母、数字以及横杠、下划线组成的字符串。
- uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
- path,匹配任何非空字符串,包含了路径分隔符
自定义转换器
对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:
regex类属性,字符串类型
to_python(self, value)方法,value是由类属性regex所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。to_url(self, value)方法,和to_python相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
例子:
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
使用register_converter 将其注册到URL配置中:
from django.urls import register_converter, path from . import converters, views register_converter(converters.FourDigitYearConverter, 'yyyy') urlpatterns = [ path('articles/2003/', views.special_case_2003), path('articles/<yyyy:year>/', views.year_archive), ... ]
re_path捕获参数的方式
每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
传递到视图函数views.year_archive() 中的year 参数永远是一个字符串类型。
有名分组
在path和re_path中都有一个name参数,相当于给这条路由起了个别名,当我们在视图或模板中调用时就可以使用这个别名。
当我们在修改路由的url,而在视图中是引用路由name根本不受影响,就可以大大减少修改的地方。
from django.urls import path, re_path from . import views urlpatterns = [ path('', views.ArticleList.as_view(), name='article_list'), path('blog/article/<int:id>/', views.article, name = 'article'), re_path(r'^blog/article/(?P<id>\d+)/$', views.article, name='article'), ]
# 模板中 # 方法1: 使用命名URL <a href="{% url 'article' id %}">Article</a> # 方法2: 使用常规URL - 不建议 <a href="blog/article/id">Article</a> # 视图中 def xxx(id): ... return redict('article') # 跳转到 name=article 的那个url ''' 在视图中当需要用到该命名的路由对应的url时,可以进行反向解析 ''' from django.urls import reverse # output blog/article/id reverse('blog:article', args=[id])
分发
''' 在设计url时往往不会将所有的路由都放在同一个urls.py中,而是将路由按不同的app进行分发 ''' from django.urls import path,re_path,include from app01 import views urlpatterns = [ path(r'admin/', admin.site.urls), path(r'blog/', include('blog.urls',namespace='blog')), ] ''' 使用include进行分发时,在不同的urls.py中就有可能出现相同的路由命名。那么如何区分呢? include()中有个namespace参数,意思为名空间。在视图或模板中使用时就按 namespace:name 格式进行定位路由 ''' def xxx(request,id): .... return redict('blog:article')

浙公网安备 33010602011771号