Django的路由

2.1 认识路由

URL是网站Web服务的入口。用户在浏览器中输入URL发出请求之后,后端的Django应用会在路由系统中根据URL查找并运行对应的视图函数,然后返回信息到浏览器中。Django的路由系统也被称为URL conf,这反映了URL和视图函数的映射关系:遇到某个URL就执行对应的视图函数。
当我们创建一个Django项目的时候,在项目目录下面会生成一个urls.py文件。在该文件中定义了Django项目的主要路由信息。该文件也是整个项目路由解析的入口。除此之外,在新建的应用中也可以使用独立的路由配置文件urls.py。但应用中的urls.py需要手动创建。这里我们接着前面的项目进行练习。

前面文章回顾: 第1章- Django入门简介

2.1.1 路由系统的基本配置

在项目的urls.py中,有一个名称为“urlpatterns”的列表,其中存放着项目中的URL路由规则,以下代码作为一个例子:

from django.contrib import admin 
from django.urls import path,include
from app import views 


urlpatterns = [
    path('index/',views.index),  # 访问路由,制定视图函数 
    path('index/',views.index,name='index'), # 第二种写法
    # 上述写法二选其一,推荐第二种
    path('admin/',admin.site.urls),  # admin模块下的路由配置  
]

在上面的代码中,默认导入了admin模块和path()方法,并在urlpatterns列表中指向admin后台管理系统的URL管理规则(这是一条默认的路由规则)。该urlpatterns列表中定义的路由为整个项目的根路由。
一个path()函数对应一条路由规则。当用户请求"index/"这个URL的时候,通过配置项找到app应用下面view.py中对应的视图函数index()执行并返回结果。
path()函数的语法格式如下:

path(路由,视图函数,别名)

2.1.2 [实战]用“路由包含”简化项目的复杂度

随着业务模块越来越多,路由规则也会越来越复杂。可以用“路由包含”来简化项目的复杂度:为每一个应用创建一个urls.py文件,把相关的路由配置都放在每个应用的urls.py文件中。这样,当用户发起请求时,会从根路由开始寻找每个应用的路由信息,生成一个完整的路由列表。当Django从当前请求中获取路由地址后,会先在这个路由列表中进行匹配,然后执行路由信息所关联的视图函数,从而完成整个请求过程。
1.路由配置规则
在项目的urls文件中,urlpatterns列表会从上到下进行匹配。

  • 如果匹配成功,则调用path()函数中的第2个参数所指定的视图函数,且不会再往下继续匹配。
  • 如果匹配不成功,则返回404错误。
  • 如果在应用中定义了子路由,则在根路由中使用include(‘应用名.urls’)来加载子路由。如果URL的第1部分被匹配,则其余部分会在子路由进行匹配。
  • 路由信息一般以“/”结尾。

2.实战
路由包含的写法是Django必学的一个技能点,接下来对项目中的应用的路由进行管理。我们之前只创建了一个应用:app。这里我们再创建两个应用,以此来更好的理解路由包含的使用方法。
创建应用:

$ python manage.py startapp app1
$ python manage.py startapp app2

这里可以看到应用app1和app2被创建。
请添加图片描述

  • (1) 这里我们在“myshop/urls.py”添加如下代码。其中,include()函数的参数为应用的URL配置文件:
urlpatterns = [
    #path('index/',views.index),  # 访问路由,制定视图函数 
    path('index/',views.index,name='index'), # 第二种写法
    path('',include('app1.urls')), 
    path('',include('app2.urls')),
    
    path('admin/',admin.site.urls),  # admin模块下的路由配置  
]
  • (2) 新建应用路由文件“app1/urls.py”,“app2/urls.py”,在其中添加如下代码:
from django.urls import path
from app2 import views   # 这里记得调用对应的app

urlpatterns = [
    path('app1/index/',views.index), # 在app2中写:'app2/index'
]

在这里插入图片描述

  • (3) 分别在"app1/views.py"和"app2/views.py"增加视图函数index(),代码如下所示:
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("这里是app1中的index方法。")  # 同理,app2修改一下名称即可

请添加图片描述

  • (4) 运行结果如下所示:

当访问"http://127.0.0.1:8000/app1/index/“,结果如下:
请添加图片描述
当访问"http://127.0.0.1:8000/app2/index/”,结果如下:
请添加图片描述
同样的,我们在控制台也是可以看到请求路由的信息:
请添加图片描述

2.1.3 解析路由参数

在浏览新闻网站的某个新闻详情网页的时候,URL地址一般为“show/1/”,“show/2/”这样的格式,我们不可能为所有的新闻详情页面都预先配置好路由规则,所以需要引入URL参数进行动态的配置。

1.编写带URL参数的路由
这里通过一个例子来学习带URL参数的路由。

  • (1)这里我们编写app1和app2下面的urls.py的代码,增加配置路由:
urlpatterns = [
    path('app1/show/<int:id>/',views.show), # app2中同理
]
  • (2)分别编写app1和app2中的views.py,增加视图函数show()
def show(request,id):
    return HttpResponse("app1中的show方法,参数为id,值为"+str(id))
  • (3)这里访问一下对应的路由:
    请添加图片描述
    请添加图片描述
    2.介绍URL参数
    在路由规则:"path(‘app1/show/<int.id>/’,views.show)"中,<>中的内容被称为URL参数。其余法格式如下:
<参数数据类型:参数名称>
举例:
<uuid:id>
<str:name>

URL参数有4种数据类型:

参数数据类型说明
str任意非空字符,不包含"/",默认类型
int匹配0和正整数
slug匹配任何ASCII字符、连接符和下划线
uuid匹配一个uuid格式的字符串,该对象必须包含“-”,所有字母必须小写

3.URL参数解析的实例
这里通过实例演示URL参数解析。

  • (1)打开应用路由文件"app1/urls.py",添加如下路由规则:
urlpatterns = [
    path('app1/article/<uuid:id>/',views.show_uuid,name='show_uuid'),
    path('app1/article/<slug:q>/',views.show_slug,name='show_slug'),
]
  • (2) 打开"app1/views.py",增加视图函数show_uuid(),如以下代码:
def show(request,id):
    return HttpResponse("app1中的show方法,参数为id,值为"+str(id))

def show_uuid(request,id):
    return HttpResponse("app1中的show_uuid方法,参数为id,值为"+str(id))

def show_slug(request,q):
    return HttpResponse("app1中的show_slug方法吗,参数为q,值为"+str(q))
  • (3) 这里访问一下上面新增加的两条路由规则:
(1)http://127.0.0.1:8000/app1/article/4b301c53-5fe6-4f71-9d23-a8935e80f641/

请添加图片描述

(2)http://127.0.0.1:8000/app1/article/shirong123/

请添加图片描述

  • (4) 补充说明:当我们测试uuid参数的时候,随机输入的uuid会被识别为slug参数,这是因为在这里uuid参数格式做了要求,具体如下:
UUID识别码格式:
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}

这里为了测试方便我们可以用python自带的uuid库来完成uuid的随机生成:

macbook@shirongediannao ~ % python3
Python 3.9.13 (main, May 24 2022, 21:28:44) 
[Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import uuid
>>> uuid.uuid4()
UUID('a4631fc6-32c4-4d96-8c01-79d0e85ae864')
>>> 

2.1.4 [实战]用re_path()方法正则匹配复杂路由

re_path()方法和path()方法作用一样。在re_path()方法中编写URL时可以使用正则表达式,所以在这里我们用它。

  • 1.路由中的正则表达式
    路由中的正则表达式的语法格式如下:
(?P<name>pattern)

其中,name是匹配的字符串名称,pattern是要匹配的模式。常见的正则表达式如下:

正则表达式说明
.匹配任意单个字符
\d匹配任意一个数字
\w匹配字母,数字,下划线
*匹配0个或者多个字符(如"\d*"代表0个或者多个数字)
[a-z]匹配a~z中任意一个小写字符
{1,5}匹配1~5个字符
  • 2.实例
    这里通过一个实例来演示路由中的正则表达式:
    (1)修改app1中的urls.py,在其中添加如下代码:
from django.urls import path,re_path # 这里需要补上re_path,否则会报错缺少依赖
from app1 import views


urlpatterns = [
    path('app1/article/<uuid:id>/',views.show_uuid,name='show_uuid'),
    path('app1/article/<slug:q>/',views.show_slug,name='show_slug'),
    
    re_path(r'^app1/list/(?P<year>\d{4})/',views.article_list),
    re_path(r'^app1/page/(?P<page>\d+)&key=(?P<key>\w+)',views.article_page,name="article_page"),
]

(2)解析代码

app1/list/(?P<year>\d{4})/
解释:接收以“app1/list/”开头、后面跟4位整数的路由。

app1/page/(?P<page>\d+)&key=(?P<key>\w+)
解释:接收以“app1/page/”开头、后面跟任意整数,且第2个参数可以是字母、数字和下划线的路由。

(3)编辑app1中的views.py代码,增加视图函数article_list()和article_page():

def article_list(request,year):
    return HttpResponse("app1中的article_list方法,参数为year,指定4位,值为"+str(year))

def article_page(request,page,key):
    return 	HttpResponse("app1中的article_page方法,参数为page,任意数字,值为"+str(page)+" 参数key,字母数字下划线,值为"+key)

(4)根据上述编写的路由规则访问这两个路由

http://127.0.0.1:8000/app1/list/2023/

请添加图片描述

http://127.0.0.1:8000/app1/page/10&key=shi_rong

请添加图片描述

2.1.5 反向解析路由

在Django的路由配置中,可以给一个路由配置项目名,然后在视图函数或模板的HTML文件中进行调用。

  • 1.介绍
    先了解以下的路由配置:
path('app1/url_reverse/',views.url_reverse,name='app1/url_reverse'),

说明如下:
(1)在name后可以跟任意字符串。为了避免冲突,建议使用的规则名为:“应用名_配置项目名称”
(2)name相当如配置项的别名。有了这个别名就可以在视图函数或者模板的HTML文件中调用它

根据name得到的路由配置项中的URL地址,被称为“反向解析路由”。这样的好处是:只要name不变,URL地址可以任意改变。

  • 2.实例
    这里通过一个实例来学习反向解析路由

(1)打开app1中的urls.py,增加一段反向解析路由,如以下代码所示:

path('app1/url_reverse',views.url_reverse,name='app1_url_reverse'),

(2)打开app1中的views.py,增加视图函数url_reverse(),如以下代码所示:

# 在最上面导入reverse
...
from django.urls import reverse

...
def url_reverse(request):
    # 使用reverse()方法反向解析
    print("在views()函数中使用reverse()方法解析的结果:"+reverse("app1_url_reverse![请添加图片描述](https://img-blog.csdnimg.cn/912ff80874c447229244946d91947b87.png)
"))
    return render(request,"1/url_reverse.html")

(3)在template中新建文件url_reverse.html:

<div>
    在HTML中使用url标签进行反向解析
    <br>
    {% url 'app1_url_reverse' %}
<div>

(4)运行后访问路由:http://127.0.0.1:8000/app1/url_reverse/
请添加图片描述
这里我们可以发现在HTML代码中调用的是:app1_url_reverse,然而最后调用的是:url_reverse,也就是说在urls.py中只要增加反向解析的路由,就可以实现该功能。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如此李想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值