Django框架之路由详解
对于优秀的Web应用来说,使用简洁,优雅的URL模式是一个非常值得重视的细节。
Django允许您自由地设计自己的URL,无需框架束缚。
为了给一个应用设计URL,您需要创建一个Python模块,通常被称为 URLconf (URL配置)。
这个模块是纯粹的Python代码,包含URL模式(简单的正则表达式)到Python函数(你的视图)的简单映射。
Django如何处理一个请求
当一个用户请求Django站点的一个页面,下面是Django系统决定执行以下Python代码使用的算法:
Django,确定使用根URLconf模块。通常,这是
ROOT_URLCONF
设置的值,但如果放置HttpRequest
对象拥有urlconf
属性(通过中间件设置),则其值将被替换为ROOT_URLCONF
设置。Django加载该Python模块并寻找可用的
urlpatterns
。它是django.urls.path()
和(或)django.urls.re_path()
实例的序列(sequence)。Django依次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来。
一旦有URL匹配成功,Djagno引入并调用相关的视图,这个视图是一个简单的Python函数(或基于类的
视图基于
类的视图)。- 一个
HttpRequest
实例。 - 如果匹配的URL返回没有命名组,那么来自正则表达式中的匹配项将作为位置参数提供。
- 关键字参数由路径表达式匹配的任何命名部分组成,并由
django.urls.path()
或django.urls.re_path()
的可选kwargs
参数中指定的任何参数覆盖。
- 一个
- 如果没有URL被匹配,或者匹配过程中出现了异常,Django会调用一个适当的错误处理视图。参加下面的错误处理( 错误处理)。
Django框架中的路由定义方式
- django.urls.path()
- django.urls.re_path()
区别:
path(). 是定义字符串为url规则,
re_path() 可以是字符串或者字符串和正则的组合
path('abc/',views.abcdef),
re_path(r'^\w{3}/$',views.strdef),
# ^ 在正则表达式中 代表 限制开始
# \w 在正则表达式中 代表 单个的 字母/数字/下划线
# {3} 在正则表达式中 代表匹配的次数
# $ 在正则表达式中 代表 限制结尾
# '^\w{3}/$' 就整体代表 字母/数字/下划线 三位组成的 字符串 以 /结尾
# abb/a12/a_11/ 不符合 字符长度不对,开始和结尾不对。
Django框架中路由的参数捕获
1.使用path可以捕获url中的一部分内容作为视图函数的关键字参数进行传递
# urls
# 路由中可以使用<类型:参数名>的方式来捕获url中的一部分作为参数使用
path('arts/<int:year>/', views.year_archive),
path('arts/<int:year>/<int:month>/', views.month_archive),
# 路由中如果定义了参数,那么对应的视图函数中也必须定义,并且要参数名一致
def year_archive(request,year):
'''
在路由当中指定来参数,那么对应的视图函数中则必须定义该参数
'''
return HttpResponse(f'year_archive:{year}')
def month_archive(request,year,month):
return HttpResponse(f"month_archive:{year},{month}")
2.re_path 捕获url中的内容作为参数
re_path() 中可以使用 (?P<参数名>参数规则) 来捕获URL中的参数
# re_path 捕获url中的内容作为参数
re_path(r'^name/(?P<name>\w{3,8})/$',views.getname),
re_path(r'^(?P<name>\w{3,8})/p/(?P<pid>\d{8})/$',views.getnamepost),
# 非命名参数捕获,这样定义那么对应的视图函数中只要有这个行参就可以
re_path(r'^(\w{3,8})/p/(\d{8})/$',views.gnamep),
URL反向的解析
通过案例来讲解url反向解析。
假如有这样一个URL的规则是解析到 显示文章的视图的映射
# 路由 urls.py
path('get/post/<int:id>/',views.getpost)
# 视图 views.py
def getpost(request,id):
# 通过文章id获取文章数据
# 把文章内容解析到模版中
return HttpResponse(f'{id}:的文章内容。。。')
那么在需要定义链接地址的地方如 html的a链接中可以直接硬编码的方式定义链接例如
<!-- index.html -->
<a href="/get/post/3/">Python3编码规范-硬编码</a>
这样就可以在页面中,通过a链接跳转到对应的文章视图函数中,查看文章的内容。
但是这样做有一个致命的缺陷,一旦url规则发生变化或url规则较多时,非常容易出错
强烈建议不要硬编码URL
假如 把url路由的规则改变了,那么对应的链接就会失效,你能想象你需要更改整个网站中的链接的痛苦场景。
因此,Django的路由可以设置 url反向解析来一劳永逸的解决这个问题。
1.在定义对应的路由规则时,只需要给定义的路由设置name关键字参数。路由名字。
# 在定义路由时,可以指定路由的名字,在使用时通过路由名动态解析路由规则 url
path('getpost/<int:id>/',views.getpost,name="home_getpost")
2.在需要使用url的html页面中可以使用 url标签进行动态的反向解析
<!-- index.html -->
<!-- {% url '路由名' 路由捕获参数 %} -->
<a href="{% url 'home_getpost' 3 %}">Python3编码规范-反向解析</a>
3.不管你路由规则怎么变化,只要路由名称不变,那么通过反响解析的链接也不需要更改
url反向解析的使用
- html模版中 可以使用 url 标签来反向解析
- 在其他的python代码中 使用 reverse() 方法进行反向解析。django.url.reverse()