8.零基础快速入门Python Web开发——路由系统

146 阅读8分钟

路由系统

通过URL(Uniform Resource Locator,统一资源定位符)可以访问互联网上的资源——用户通过浏览器向指定URL发起请求,Web服务器接收请求并返回用户请求的资源,因此可以将URL视为用户与服务器之间交互的桥梁。

Django作为一个优秀的Web框架,提供了配置URL的路由系统,通过该路由系统,开发人员可以设计出简洁、优雅的URL。

【学习目标】:

  1. 学会编写URL
  2. 掌握URL参数的传递方法
  3. 掌握如何通过include()函数实现路由分发
  4. 熟悉URL命名与反向解析URL的方法
  5. 掌握URL命名空间

1.URL分发机制简介

URL的基本格式为“协议://域名或IP地址/文件名”。域名或IP地址在Web服务器中分配给Web站点。路径是网络资源在Web服务器中的逻辑路径。文件名通常与网络资源的物理文件名一致。

Django提供了灵魂的URL分发机制,允许用户使用任意格式的URL“路径/文件名”部分。如果使用常规的URL,从URL中可以分析出实际物理文件在系统中的路径和文件名。

Django接收到用户的请求后如何处理请求和返回响应的?如图2-1所示。

​编辑

图 3-1 处理Http请求流程

Django接收到请求的URL后,开始执行URL分发任务,以前一节课中HelloWorld项目为例。当用户浏览器输入127.0.0.1:8000后,Django内部按如下顺序执行下列操作。

(1)启用跟URL配置模块。根URL配置模块由项目配置文件settings.py 中的ROOT_URCONF变量设置。

ROOT_URLCONF=ROOT_URLCONF = 'Helloworld.urls'

  1. 加载根URL配置模块,并查找变量urlpatterns。urlpatterns是一个URL模式列表,每个列表项是一个django.urls.path()或django.urls.re_path()实例,实例代码如下。
urlpatterns = [

    path('admin/', admin.site.urls),

    path('',views.index),

]

  1. 按顺序遍历每个URL模式,在找到与请求的URL相匹配的第一个模式时停止。
  2. Django调用匹配的URL模式所映射的视图函数,将函数返回值作为响应结果返回给用户。视图函数接收下列参数:
  1. 一个HttpRequest对象实例:它封装了客户端请求的相关信息。
  2. URL参数:如果匹配的URL模式中嵌套了变量,则将URL路径中的匹配内容赋值给变量,将其作为参数传递给视图函数。
  3. Kwargs参数:向视图函数传递其他参数值。
  1. 如果没有找到匹配的URL模式,或者此过程中的任何位置引发错误,Django将调用错误处理视图。

****2. 路由配置

URL配置指使用URL解析函数建立URL与视图函数之间的映射关系,也就是设置访问视图函数的URL规则。

2 .1 URL解析函数

URL配置文件中的urlpatterns变量为URL解析函数的示例列表。Django提供了两个URL解析函数:django.urls.path()和django.urls.re_path()。它们的原型如下。

  1. path(route,view,kwargs=None,name=None)
  2. re_path(route,view,kwargs=None,name=None)

访问Django站点的URL基本格式为“协议://域名或IP地址/路径”。参数route为URL模式,用于匹配URL中的“路径”。参数view用于设置路径匹配时调用的视图函数。可选参数keywargs用来向views传递参数,可选参数name为URL起别名,主要在模板中使用。在URL反向解析时用URL模式的名称可获得访问视图函数的URL。

Path()和re_path()函数的第一个参数route都是字符串,而re_path()函数将route参数作为正则表达式使用。

下面回顾一下前一章节中HelloWorld项目中的urls.py文件代码。

from django.conf.urls import url

from . import views

urlpatterns = [

Path(‘', views.hello),

 ]

其中,“from django.conf.urls import url ”导入URL解析函数path()。“from . import views ”导入当前目录中的视图模块views(对应views.py文件)。Urlpatterns变量包含了一个URL映射。

  1. Path(‘', views.hello):第一个参数为空字符,用于匹配只使用域名或IP地址的URL,如“127.0.0.1:8000”。第二个参数“views.hello”设置了URL匹配时调用的视图函数。

2 .2 使用正则表达式匹配URL

若URL中包含如文件路径、工牌号这类不规则的信息,则使用路由转换器无法很好地匹配URL模式,此时可以使用正则表达式定义路由模式。若要使用正则表达式匹配URL,则可以使用re_path()函数,该函数语法格式如下:

re_path()函数的参数route接收一个正则表达式,其余参数与path()函数中参数的作用相同。正则表达式提供里一种灵活的字符串匹配方式。表2-1列出了常用的正则表达式。

表 2-1 常用的正则表达式

正则表达式匹配说明
^[1-9]\d*$正整数
^-[1-9]\d*$负整数
^-?[1-9]\d*$整数
^[1-9]\d*0$非负整数(正整数 + 0)
^-[1-9]\d*0$非正整数(负整数 + 0)
^[A-Za-z]+$由26个英文字母组成的字符串
^[A-Z]+$由26个英文字母的大写组成的字符串
^[a-z]+$由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$由数字和26个英文字母组成的字符串
^\w+$由数字、26个英文字母或下划线组成的字符串
^[0-9]$数字
^\d{n}$ n位的数字
^\d{n,}$至少n位的数字
^\d{m,n}$m-n位的数字
^(0[1-9][0-9])$零和非零开头的数字
^(-+)?\d+(.\d+)?$正数、负数、和小数
^[\u4e00-\u9fa5]{0,}$汉字
^[A-Za-z0-9]+[AZaz09]4,40 或 ^[A-Za-z0-9]{4,40}英文和数字
^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)$Email地址
^.{3,20}$长度为3-20的所有字符

使用re_path()函数匹配包含正则表达式的URL有两种方式。

  1. 未命名正则表达式

若正则表达式只通过小括号“()”来捕获URL的参数,但未为其命名,则它是一个未命名正则表达式,此时捕获的参数并将其以位置参数形式传递给对应视图。

  1. 命名正则表达式

命名正则表达式格式为:(?Ppattern),其中name表示分组名,pattern表示匹配的正则表达式。URL匹配成功后,捕获到的参数会作为关键字参数传递给对应的视图,因此视图中的形式参数必须和正则表达式中的分组名相同。

下面的实例创建一个项目testurl,在项目同名子文件夹中定义视图,视图函数根据请求URL不同,输出不同相应的信息。

具体操作步骤如下。

  1. 打开pycharm工具,在终端执行下面的命令创建项目testurl。
E:>django-admin startproject testurl

  1. 在“testurl\testurl”文件夹下创建views.py文件,在文件中输入下面的代码定义两个视图函数。

f

from django.http import HttpResponse



def charinurl(request):

    return HttpResponse('匹配大小写字母组成的字符串')



def numberinurl(request):

    return HttpResponse('匹配至少两位数组组成的数字字符串')

  1. 打开“testurl\testurl\urls.py”文件修改代码。配置访问视图函数的URL,代码如下。
urlpatterns = [

    path('admin/', admin.site.urls),

    re_path(r'^[A-Za-z]+$',views.charinurl),  #匹配大小写字母的

re_path(r'^\d{2,}$',views.numberinurl),  #匹配两位数以上的数字

]

  1. 在settings.py文件中,将testurl添加到INSTALLED_APP列表中,在终端输入python manage.py runserver命令,执行启动开发服务器。
  2. 在浏览器中访问http://127.0.0.1:8000/123abc,结果如图2-2所示。由于在“testurl.urls”中定义的URL模式中找不到123abc的匹配项,所以找不到页面的错误。

​编辑图 2-2 在URL中使用式子字母混合的字符串

  1. 在浏览器中访问http://127.0.0.1:8000/123,页面结构输出如图2-3所示。URL中“123”是一个数字字符串,与urls.py文件定义的第二个URL模式'^\d{2,}$'匹配,所以调用“views.NumberInUrl”函数。

​编辑

图 2-3 在URL中使用数字字符串

  1. 在浏览器中访问http://127.0.0.1:8000/abc,页面结构输出如图2-4所示。URL中“abc”是一个字母字符串,与urls.py文件定义的第二个URL模式'^[A-Za-z]+$'匹配,所以调用“views.CharInUrl”函数。

​编辑图 2-4 在URL中使用字母字符串

2.2.3 路由分发

通常情况下,一个Django项目中会包含多个应用,每个应用都可以设置多个URL,如果将项目所有的URL都保存在根URLconf中,那么URLconf会变得非常臃肿,不利于维护。因此,Django允许每个应用将URL封装到本应用的URLconf中,在根URLconf使用urls模块的include()函数将应用中的URLconf导入即可实现路由分发,路由分发的使用降低应用的URLconf与根URLconf的耦合度。

使用include()实现路由分发有两种方式。

include(module,namespace = None)           # 1.引入应用URLconf

include(pattern_list)                        # 2.引入URL模式列表

Include()函数参数的具体介绍如下。

  1. module:用于指定URLconf模块。
  2. namespace:用于指定URL模式实例的命名空间。
  3. pattern_list:用于指定一个可迭代的path或re_path实例列表。

下面的实例为项目testurl添加一个应用testinclude,为应用创建一个urls.py文件以配置URL访问应用的视图函数,分别使用引入应用URLconf和引入URL模式列表两种路由分发方式在项目testurl的URL配置包含应用的URL配置。

  1. 引入应用URLconf。

首先在项目testurl中添加应用testinclude,在testinclude中的views.py文件中定义视图函数。代码如下。

from django.http import HttpResponse



def useinclude(request):

    return  HttpResponse('求关注')

然后,在应用testinclude下创建urls.py 文件,为useinclude函数配置路由。

from django.urls import path,re_path

from . import views



urlpatterns = [

    path('sub/',views.useinclude),

]

返回项目文件同名子文件“testurl\testurl\urls.py”文件,在文件中添加URL配置。

from django.urls import path,re_path,include

from . import views



urlpatterns = [

   path('first/',include('testinclude.urls')),

]

保存修改后,在配置文件的INSTALL_APP列表中添加应用名,在浏览器中访问http://127.0.0.1:8000/first/sub/,结果如图2-5所示。

图略

本例中, path('first/',include('testinclude.urls'))包含了testinclude应用的urls.py中的URL配置。当访问first/sub/时,路由系统首先在testurl项目的跟URLconf进行URL匹配,匹配到/first/后,路由系统遍历testurl应用的URLconf,继续匹配URL其余部分,最后调用视图文件中的useinclude函数,返回响应结果。

  1. 引入URL模式列表

除了引用应用的URLconf,include()函数还可以引入URL模式列表,这种方式不需要再应用中新建urls.py,只需再项目的根URLconf中使用include()函数添加额外的URL模式列表即可。例如,将项目的URL配置文件修改为如下代码。

from django.urls import path,re_path,include

from . import views

from testinclude import views as subView

sub_urlpatterns = [

    path('sub2/',subView.useinclude),



]  

urlpatterns = [

   ...

path('ccit2/',include(sub_urlpatterns)),

]

在浏览器中访问http://127.0.0.1:8000/ccit2/sub2/

结果如图2-6所示。

图略

访问/ccit2/sub2/时,路由系统首先在testurl项目的根URLconf进行URL匹配,匹配到/ccit2/后路由系统遍历URL模式变量sub_urlpatterns中的元素,继续匹配URL的其余部分。