Django之url路由控制

URL配置(URLconf)就像Django所支撑网站的目录,它的本质是URL与要为该URL调用的视图函数之间的映射表;就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段业务逻辑代码对应执行。

1、什么是URL?

URL是统一资源定位器(Uniform Resource Locator)的缩写,也被称为网页地址,是因特网上标准的资源的地址。

  • URL举例
http://www.sohu.com/stu/intro.html
http://222.172.123.33/stu/intro.html
  • URL地址由4部分组成
第1部分:为协议:http://、ftp://等 
第2部分:为站点地址:可以是域名或IP地址
第3部分:为页面在站点中的目录:stu
第4部分:为页面名称,例如 index.html
各部分之间用“/”符号隔开。

2、Django是如何处理一个请求?

当用户从Django支持的网站请求页面时,系统将使用以下算法来确定要执行的Python代码:

Django确定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但是如果传入 HttpRequest对象具有urlconf 属性(由中间件设置),则将使用其值代替 ROOT_URLCONF设置。

Django加载该Python模块并查找变量 urlpatterns,涉及到 django.urls.path()/ 或 django.urls.re_path()实例。

Django按顺序遍历每个URL模式,并在第一个与请求的URL匹配的URL处停止,一旦其中一个URL模式匹配,Django就会导入并调用给定的views视图,该视图是Python函数(或基于类的视图)。该视图将传递以下参数:的实例对象HttpRequest

如果匹配的URL模式不包含命名组,则根据正则表达式,完全匹配的匹配项将作为位置参数提供。

如果匹配的URL模式包含命名组,则根据正则表达式,默认非完全匹配,的匹配项将作为关键字参数提供。如果关键字参数由提供的路径表达式匹配的任何命名部分组成,这些名称部分由或 的可选kwargs参数中指定的任何参数覆盖。django.urls.path()django.urls.re_path()在Django 3.0中进行了更改:在旧版本中,带有None值的关键字参数也由未提供的命名部分组成。

如果没有URL模式匹配,或者在此过程中的任何时候引发异常,Django都会调用一个适当的错误处理视图。4xx、5xx

3、url路由系统

3.0 正则匹配的本质

正则匹配本质上帮我们做的是: re.search(“规则”, “待匹配字符串”) —> re.search(“规则”, “url路径部分”)

特点是:依照匹配规则匹配符合条件的值,匹配到则返回,否则也不会报错

自上而下匹配,当匹配成功后则停止

3.1 path 正则,完全匹配

path在匹配规则前后默认加了 ^$,保证完全匹配,

# re.search("^/books/2002/$", "/books/2002")
path('/books/2002/', views.books_2002)     # 默认前后加了  ^$

path('', views.home)                       # 这种一般设置主页

3.2 re_path 正则,非完全匹配

re.search(“规则”,“待匹配字符串”)—> re.search(“re_path”,“url路径部分”)

3.2.0 没有分组,(request对象)

请求传参为:(request对象),例:books_2002(request)
re_path('/books/2002/', views.books_2002)        # 默认前后加了  ^$,(暂定4位匹配年份,左边规则,右边待匹配字符串)

3.2.1 无名分组(正则),按位置传参 (request对象,args位置参数)

使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图

请求传参为:(request对象,位置参数),例:year_articles(request, 2003)
def year_articles(request, year):

	return HttpResponse("年份筛选:"+year)
from django.urls import re_path
from app01 import views

urlpatterns = [
    re_path(r'^articles/2003/$', views.special_case_2003),    # special_case_2003(request)
    re_path(r'^articles/([0-9]{4})/$', views.year_articles),          # year_articles(request, 2012)
    re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_articles),     # month_articles(request, 2003, 12)
    re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.articles_detail),   #  views.article_detail(request, 2003, 03, 03)
]

注意:

  • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
  • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  • 每个正则表达式前面的r 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义
 一些请求的例子:
 
/articles/2005/03/  请求将匹配列表中的第三个模式。Django 将调用函数     views.month_archive(request, '2005', '03')。
/articles/2005/3/   不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/     将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。请像这样*插入一些特殊的情况来探测匹配的次序。
/articles/2003      django会自动给URL 补齐一个反斜线结尾,将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配
/articles/2003/03/03/     将匹配最后一个模式。Django 将调用函数   views.article_detail(request, '2003', '03', '03')。
 无名分组,位置参数:(有名按分组,无名按位置)
 (正则):正则分组,books_year(request,d{4}) ,则分组内容作为第二个形参传过来(本质上是通过正则筛选过滤),以此类推
 re_path("/books/(\d{4}/)", views.books_year)

3.2.2 有名分组 (?P<name>正则),按关键字传参 ,(request, key1=value1, key2=value2)

在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以 关键字参数传递给视图。在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中 name 是组的名称,pattern 是要匹配的模式。

请求传参为:(request对象,关键字参数),例:(request, 2003, 12)
def books_year_month(request, year, month):

	return HttpResponse("月份筛选 年:"+year+" 月:" + month)
# (?P<name>正则):有名分组,关键字参数:函数传参的过程就是变量赋值的过程,
re_path(r'books/(?P<year>\d{4})/(?P<month>\d{2})/', views.books_year_month),  # books_year_month(request, year=2003, month12)

3.3 路由分发,include()

与models.py和views.py一样,如果我们希望每一个app拥有自己的urls.py,则需要对全局urls.py进行分发解耦

# 在全局设置路由分发指向
	  path("app01/", include("app01.urls"))
	  # https://127.0.0.1/app01/  会将app01自动拼接
''' 
"""djUrls URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/',include('blog.urls')),
]

在blog应用下创建urls.py文件:

from django.urls import re_path
from app01 import views


urlpatterns = [
    re_path('articles/(\d{4})',views.year_articles),
]
上一篇:IE浏览器关于ajax的缓存机制


下一篇:【PostgreSQL技巧】PostgreSQL中的物化视图与汇总表比较