Django5路由定义与使用
2850字约10分钟
2025-02-16
Django5路由定义
一个完整的路由包含:路由地址、视图函数(或者视图类)、可选变量和路由命名。
路由称为URL (Uniform Resource Locator,统一资源定位符),也可以称为URLconf,是对可以从互联 网上得到的资源位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件 都有一个唯一的路由,用于指出网站文件的路径位置。简单地说,路由可视为我们常说的网址,每个网 址代表不同的网页。
前面的Hello World项目。我们请求的地址:
http://127.0.0.1:8000/index/
就是一个路由地址。
index/ 请求地址,根据urls.py配置文件,找到对应的helloWorld views下的index视图函数;
然后最终执行index视图函数,然后到index.html页面
Django5路由变量
在平时开发中,有时候一个路由可以代表多个不同的页面,比如博客系统里面,有1千个博客页面,按照 前面学习的方式,需要写1千个路由才能实现,这种做法显然不可取,维护也麻烦。我们可以通过路由变 量,来实现一个路由代表多个页面。
路由的变量类型有字符类型、整型、slug 和 uuid,最为常用的是字符类型和整型。各个类型说明如下。
- 字符类型:匹配任何非空字符串,但不含斜杠。如果没有指定类型,就默认使用该类型。 整型:匹配О和正整数。
- slug:可理解为注释、后缀或附属等概念,常作为路由的解释性字符。可匹配任何ASCII字符以及连 接符和下画线,能使路由更加清晰易懂。比如网页的标题是“15岁的孩子”,其路由地址可以设置为 “15-sui-de-hai-zi”。
- uuid:匹配一个uuid格式的对象。为了防止冲突,规定必须使用“”并且所有字母必须小写,例如 175194d3-6885-437e-a8a8-6c231e272f00。
下面列举实例一 博客帖子请求:
首先urls.py里定义路由映射:
path('blog/<int:id>', helloWorld.views.blog)
views.py里再定义blog函数实现:
def blog(request, id):
return HttpResponse('id是' + str(id) + "的博客页面")
这样,我们就实现了一个带变量的路由的多个博客页面的实现。
当然我们也可以带多个路由变量。让博客的路由地址,在带上年月日变量。
urls.py修改
path('blog2/<int:year>/<int:month>/<int:day>/<int:id>', helloWorld.views.blog2)
views.py修改
def blog2(request, year, month, day, id):
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + '/' + 'id是' + str(id) + "的博客页面")
运行测试:
Django5正则路由
有时候我们为了更好的进行路由匹配,可以用正则表达式。
比如前面讲的日期的路由变量,其实是有点问题的。
我们月份输入333,也是满足条件的。但是不符合实际,实际情况月份最多两位数。
所以这时候,我们可以用正则表达式来限制。
urls.py修改:
re_path('blog3/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})',helloWorld.views.blog3)
views.py添加blogs方法:
def blog3(request, year, month, day):
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + '的博客页面')
这里有几个正则的注意点:
第一:正则urls匹配,必须用re_path方法;
第二:正则表达式?P开头是固定格式;
运行测试:
Django5路由重定向
重定向称为HTTP协议重定向,也可以称为网页跳转,它对应的HTTP状态码为301、302、303、307、 308。简单来说,网页重定向就是在浏览器访问某个网页的时候,这个网页不提供响应内容,而是自动 跳转到其他网址,由其他网址来生成响应内容。
Django的网页重定向有两种方式:
第一种方式是路由重定向;
第二种方式是自定义视图的重定向。
两种重定向方式各有优点,前者是使用Django内置的视图类RedirectView实现的,默认支持HTTP的GET 请求;后者是在自定义视图的响应状态设置重定向,能让开发者实现多方面的开发需求。
我们分别用实例来演示下这两种方式:
路由重定向
路由重定向方式,我们用RedirectView实现,在urls.py里面,我们再加一个路由代码:
path('redirectTo', RedirectView.as_view(url="index/"))
请求redirectTo,直接重定向到 index/ 地址
运行测试,请求:
http://127.0.0.1:8000/redirectTo
自动重定向到index,状态是302。
自定义视图重定向
更多的情况,我们平时开发用的是自定义视图重定向,视图代码里,通过逻辑判断,通过redirect方法 来实现具体的页面重定向,使用更加灵活。
我们改造下前面的views.py下的blog函数:假如id是0,重定向到错误静态页面。
def blog(request, id):
if id == 0:
return redirect("/static/error.html")
else:
return HttpResponse('id是' + str(id) + "的博客页面")
static目录下新建一个error.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
系统运行有问题!
</body>
</html>
当然你也可以项目根目录下再新建一个目录,比如common,然后 STATICFILES_DIRS 静态资源文件集合 里,加下 BASE_DIR / "common",把error.html放到common目录下,我们也是可以通过static/请求地 址访问的。当然如果你觉得static/请求名称不好,也可以修改 STATIC_URL 参数 比如 改成 common/ 也 行,你就可以通过 common/ 也访问你的静态资源文件。
我们访问
http://127.0.0.1:8000/blog/0
302状态,自动跳转到了error.html错误页面。
访问其他id是正常的。
Django5命名空间namespace
当我们网站项目规模越来越多,子项目很多的时候,为了方便管理路由地址,我们可以采用命名空间 namespace来对路由地址根据子项目分类。
我们通过django manage.py自带的startapp命令新建两个项目,分别是user和order
我们分别添加urls.py到user和order项目里去。
以及加下代码:
user项目的urls.py:
from django.contrib import admin
from django.urls import path
from user import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
]
user项目的views.py
def index(request):
return HttpResponse("用户信息")
order项目的urls.py:
from django.contrib import admin
from django.urls import path
from order import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('list/', views.list),
]
order项目的views.py:
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("订单信息")
def list(request):
return HttpResponse("订单列表")
接下来,我们在主项目里,加下映射:
path('user/', include(('user.urls', 'user'), namespace='user')),
path('order/', include(('order.urls', 'order'), namespace='order'))
说明下:
include(('user.urls', 'user') 相当于找到user项目的urls.py文件。
namespace='user' 给这个映射取名是user,一般是根据项目名称来取。
第一个参数 'user/' 标识 user/开头的请求,都由user项目的urls.py去管理处理映射关系。
通过这种命名空间,我们可以把复杂项目的路由映射拆分,升级维护会方便很多。
Django5路由命名与反向解析reverse与resolve
我们在urls.py里定义的路由信息,有时候需要动态获取路由信息,然后进行一些处理,统计,日志等操 作,这时候我们需要在其他代码里用到路由信息,比如views.py,后面要学到的模型models.py, Admin系统等,因此我们引入路由反向解析reverse与resolve方法,再使用这两个方法前,我们还需要 给路由取名,否则我们无法找到我们需要的那个路由的信息。reverse方法根据路由名称得到路由地址, resolve方法根据路由地址得到路由所有信息。
我们先举一个简单例子来体会下吧。
在order项目的urls.py里,我们对index/和list/请求路由分别取名index和list
然后修改views.py的index方法:
def index(request):
route_url = reverse('order:index')
print("reverse反向解析得到路由地址:" + route_url)
result = resolve(route_url)
print("resolve通过路由地址得到路由信息:" + str(result))
return HttpResponse("订单信息")
我们运行请求:
http://127.0.0.1:8000/order/index/
控制台输出:
reverse反向解析得到路由地址:/order/index/
resolve通过路由地址得到路由信息:ResolverMatch(func=order.views.index, args=(),
kwargs={}, url_name='index', app_names=['order'], namespaces=['order'],
route='order/index/')
resolve返回对象属性介绍:
函数方法 | 说明 |
---|---|
func | 路由的视图函数对象或视图类对象 |
args | 以列表格式获取路由的变量信息 |
kwargs | 以字典格式获取路由的变量信息 |
url_name | 获取路由命名name |
app names | 与app name功能一致,但以列表格式表示 |
namespaces | 与namespace功能一致,但以列表格式表示 |
route | 获取整个路由的名称,包括命名空间 |
这里我们在修改下项目,来讲下参数的运用。
order的urls.py的list请求加下年月日路由变量
path('list/<int:year>/<int:month>/<int:day>/', views.list, name="list")
对应的views.py的list方法我们也进行修改,要加上三个路由变量
def list(request, year, month, day):
kwargs = {'year': year - 1, 'month': month + 1, 'day': day}
args = [year, month, day]
# route_url = reverse('order:list', args=args)
route_url = reverse('order:list', kwargs=kwargs)
print("reverse反向解析得到路由地址:" + route_url)
result = resolve(route_url)
print("resolve通过路由地址得到路由信息:" + str(result))
return HttpResponse("订单列表")
进行反向解析路由的时候,我们也可以带上路由实参,可以通过kwargs字典键值对,也可以通过args元组;
测试请求地址: http://127.0.0.1:8000/order/list/2010/11/11/
控制台输出:
reverse反向解析得到路由地址:/order/list/2009/12/11/
resolve通过路由地址得到路由信息:ResolverMatch(func=order.views.list, args=(),
kwargs={'year': 2009, 'month': 12, 'day': 11}, url_name='list', app_names=
['order'], namespaces=['order'],
route='order/list/<int:year>/<int:month>/<int:day>/', captured_kwargs={'year':
2009, 'month': 12, 'day': 11})
点开reverse方法:
必须参数viewname,以及一些可选参数:
- viewname:代表路由命名或可调用视图对象,一般情况下是以路由命名name来生成路由地址的。
- urlconf:设置反向解析的URLconf模块。默认情况下,使用配置文件 settings.py 的 ROOT_URLCONF属性( 主项目文件夹的urls.py ).
- args:以列表方式传递路由地址变量,列表元素顺序和数量应与路由地址变量的顺序和数量一致。
- kwargs:以字典方式传递路由地址变量,字典的键必须对应路由地址变量名,字典的键值对数量与 变量的数量一致。
- current app:提示当前正在执行的视图所在的项目应用,主要起到提示作用,在功能上并无实质的 作用。
点开resolve方法:
就两个参数:
- path:代表路由地址,通过路由地址来获取对应的路由对象信息。
- urlconf:设置反向解析的_URLconf模块。默认情况下,使用配置文件 settings.py 的 ROOT_URLCONF属性( 主项目文件夹的urls.py ).