一、普通路由参数
在路由规则中以<参数数据类型:参数名称>的方式配置,有4种数据类型,如下表
参数数据类型 | 说明 |
str | 任意非空字符串,不包含”/”,默认类型 |
int | 0和正整数 |
slug | 任何ASCII字符、连接符和下划线 |
uuid | 以”-”连接的UUID格式字符串,所有字母必须小写 |
配置示例如下:
path("show_param_int/<int:param_int>", views.show_param_int),
path("show_param_str/<str:param_str>", views.show_param_str),
path("show_param_slug/<slug:param_slug>", views.show_param_slug),
path("show_param_uuid/<uuid:param_uuid>", views.show_param_uuid),
传递参数示例如下:
<a href="/my/show_param_int/11">传递int参数</a>
<a href="/my/show_param_str/一个字符串参数">传递str参数</a>
<a href="/my/show_param_slug/abcd_1234">传递slug参数</a>
<a href="/my/show_param_uuid/01234567-abcd-1234-5678-012345678912">传递uuid参数</a>
二、复杂路由re_path
re_path()方法中编写URL可以使用正则表达式,功能更加强大,路由中正则表达式的语法格式如下:
(?P<name>pattern)
其中name是匹配的字符串,pattern是要匹配的模式,具体示例如下:
re_path("show_re_path/(?P<year>\\d{4})&key=(?P<key>\\w+)", views.show_re_path),
传递参数示例如下:
<a href="/my/show_re_path/2024&key=abc">传递参数(re_path()方法正则匹配)</a>
三、反向解析路由
Django配置路由项的时候有一个name参数用来配置路由项的别名,示例如下:
path("", views.index, name="my_index"),
这个别名主要是为了方便在项目其他地方(视图函数或html模板)链接到该项对应的页面,别名在项目中应该是唯一的,推荐命名规则为”模块名_配置项名称”,比如上面配置的my_index表示这个是my模块的主页。视图函数中要得到my_index的路由可以用reverse('my_index'),html模板中要得到my_index的路由可以用{% url 'my_index' %}。
四、代码示例
1、定义路由
from django.urls import path, re_path
from . import views
urlpatterns = [
path("", views.index, name="my_index"),
path("show_param_int/<int:param_int>", views.show_param_int),
path("show_param_str/<str:param_str>", views.show_param_str),
path("show_param_slug/<slug:param_slug>", views.show_param_slug),
path("show_param_uuid/<uuid:param_uuid>", views.show_param_uuid),
re_path("show_re_path/(?P<year>\\d{4})&key=(?P<key>\\w+)", views.show_re_path),
path("show_url_reverse/", views.show_url_reverse, name="my_show_url_reverse"),
]
2、路由函数
from django.shortcuts import render, reverse
from django.http import HttpResponse
def index(request):
return render(request, "my/index.html")
# return HttpResponse("我的模块")
def show_param_int(request, param_int: int):
# print(reverse('show_param_int'))
context = {"param_int": param_int}
return render(request, "my/show_param_int.html", context)
def show_param_str(request, param_str: str):
context = {"param_str": param_str}
return render(request, "my/show_param_str.html", context)
def show_param_slug(request, param_slug: int):
context = {"param_slug": param_slug}
return render(request, "my/show_param_slug.html", context)
def show_param_uuid(request, param_uuid: int):
context = {"param_uuid": param_uuid}
return render(request, "my/show_param_uuid.html", context)
def show_re_path(request, year: int, key: str):
# print(reverse('show_re_path'))
context = {"year": year, "key": key}
return render(request, "my/show_re_path.html", context)
def show_url_reverse(request):
print(reverse('my_show_url_reverse'))
return render(request, "my/show_url_reverse.html")
3、视图模板
3.1、index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>我的模块</h1>
<ul>
<li>
<a href="/my/show_param_int/11">传递int参数</a>
</li>
<li>
<a href="/my/show_param_str/一个字符串参数">传递str参数</a>
</li>
<li>
<a href="/my/show_param_slug/abcd_1234">传递slug参数</a>
</li>
<li>
<a href="/my/show_param_uuid/01234567-abcd-1234-5678-012345678912">传递uuid参数</a>
</li>
<li>
<a href="/my/show_re_path/2024&key=abc">传递参数(re_path()方法正则匹配)</a>
</li>
<li>
<a href="{% url 'my_show_url_reverse' %}">url反向解析</a>
</li>
</ul>
</body>
</html>
3.2、show_param_int.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>传入的参数是:{{ param_int }}</h1>
<br/>
<a href="{% url 'my_index' %}">返回我的模块</a>
</body>
</html>
3.3、show_param_str.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>传入的参数是:{{ param_str }}</h1>
<br/>
<a href="{% url 'my_index' %}">返回我的模块</a>
</body>
</html>
3.4、show_param_slug.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>传入的参数是:{{ param_slug }}</h1>
<br/>
<a href="{% url 'my_index' %}">返回我的模块</a>
</body>
</html>
3.5、show_param_uuid.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>传入的参数是:{{ param_uuid }}</h1>
<br/>
<a href="{% url 'my_index' %}">返回我的模块</a>
</body>
</html>
3.6、show_re_path.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>传入的参数是(year:{{ year }},key:{{ key }})</h1>
<br/>
<a href="{% url 'my_index' %}">返回我的模块</a>
</body>
</html>
3.7、show_url_reverse.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的模块</title>
</head>
<body>
<h1>my_show_url_reverse完整URL是:{% url 'my_show_url_reverse' %}</h1>
<br/>
<a href="{% url 'my_index' %}">返回我的模块</a>
</body>
</html>
五、多级路由
针对helloWorld项目我们有一个app(ch2),然后ch2下面还有一个子目录sub,我们先分别看一下三个层级的路由配置:
helloWord\urls.py如下:
ch2\urls.py如下:
ch2\sub\urls.py如下:
这里http://127.0.0.1:8000/为网站主页地址,在HTML模板中的链接方式如下:
<a href="{% url 'index' %}">主页</a>
http://127.0.0.1:8000/ch2/为app(ch2)的主页地址,在HTML模板中的链接方式如下:
<a href="{% url 'ch2:index' %}">ch2</a>
<a href="{% url 'ch2_:index' %}">ch2_namespace</a>
注意:主路由包含ch2路由的时候使用了namespace--path("ch2/", include("ch2.urls", namespace="ch2_"))
,所以可以用namespace的方式来替换ch2的app_name使用。
http://127.0.0.1:8000/ch2/sub/为app(ch2)下面子目录sub的主页地址,在HTML模板中的链接方式如下:
<a href="{% url 'ch2:ch2_sub:index' %}">ch2_sub</a>