一、Django 的路由
路由,既 URL 地址,每个 URL 都表示不同的页面,每个 URL 都会 views.py 中的一个视图函数。Django 项目根目录中的 urls.py 是根路由,可以集合所有应用的路由,每个应用下可以创建自己的 urls.py,这个 urls.py 是属于应用独有的路由
路由与视图函数绑定
使用 PyCharm 创建一个新的 Django 项目 django_urls_views,并创建 xray 应用,在 xray 应用下的 views.py 中创建一个视图函数 index(),该函数返回一个字符串。
from django.shortcuts import render, HttpResponse # Create your views here. def index(request): return HttpResponse("This is index of Xray") 复制代码
接着在项目的根 URL 中配置路由,并与 xray 应用下的 index 视图函数绑定
from django.contrib import admin # 导入 URL 模块 from django.urls import path # 导入视图函数 from xray import views # 项目 URL 列表,每个一个元素都表示一个 URL,每一个 URL 对应一个视图函数 urlpatterns = [ path('admin/', admin.site.urls), path('xray/index/', views.index) ] 复制代码
启动应用,在浏览器中访问地址 /xray/index/
页面显示的内容符合预期,但是当项目中的应用比较多的时候,这种直接在根 URL 中定义路由的方式是不推荐的,这样会使得根 URL 中定义的路由非常多,不好管理。
可以在每个应用中创建一个自己的 urls.py,在其中定义该应用包含的所有的路由,再在根路由中定义每一个应用的映射。
在 xray 应用文件夹下创建 urls.py,仿照根 urls.py 创建 index 函数的路由。
from django.urls import path from xray import views urlpatterns = [ path('index/', views.index) ] 复制代码
修改根路径下的 urls.py
from django.contrib import admin from django.urls import path, include # 导入 xray 应用下的 urls.py from xray import urls as xray_urls urlpatterns = [ path('admin/', admin.site.urls), path('xray/', include(xray_urls)) ] 复制代码
启动应用,在浏览器中再次访问地址 /xray/index/
显示内容符合预期,说明修改成功,因此所有关于 xray 项目的路由都可以在该项目下的 urls.py 中定义。
二、Django 路由中的参数
在 URL 中可以通过在 ?
后面通过添加键值对 key=value
的方式来传递参数,当有多个键值对的时候使用 &
来连接,如 http://127.0.0.1:8000/xray/index?name=stark&address=newyork
。
也可以通过路径本身来传递参数,如 http://127.0.0.1:8000/xray/index/stark/
URL 中参数的类型可以是以下几种类型:
- 字符串类型:匹配任何非空字符串,但不包括斜杠,在不指定类型的前提下,默认字符串类型
<str:name>
- 整型:匹配 0 和正整数
<int:age>
- slug:可以理解为注释、后缀或者负数等概念
<slug:day>
- uuid:匹配一个 uuid 格式的对象
<uuid:uid>
在 Django 2.0 以前是使用正则表达式来匹配路径中参数的类型的,如
url(r'^add/(?P<name\w+>)/(?P<age>\d+)$') 复制代码
其中 ^
和 $
表示匹配开始和结束,()
表示一个变量或字符,w+
表示匹配 1 个或者多个包括下划线在内的任何字符,既 name 变量的取值可以是包括下划线在内的任何字符,d+
表示匹配一个或者多个数字。
在 urls.py 中设置路由时,还支持给路由定义一个别名,这个别名在模板中做跳转或者其他视图函数中做重定向时可以用到。
path('/xray/index', views.index, name='xray_index') 复制代码
URL 传递参数到后端的视图函数中有两种获取方式,如果是通过 ?
传递的参数,可以直接通过 request.GET.get(参数名)
的方式来获取。
如果是路径参数既通过 /
来分割的参数,可以直接将参数名放在视图函数的参数中,这样会把路径中具体的参数值保存到视图函数中的对应参数内。
def index(request, 参数1, 参数2): print(参数1, 参数2) 复制代码
获取请求路径中 ?
后传递的参数
在 xray 应用的 views.py 文件中增加视图函数 tango
def tango(request): team = request.GET.get("team") print("请求中通过 `?` 传递的参数的值为: {}".format(team)) return HttpResponse('This is Tango 5, Do you read?') 复制代码
在 urls.py 中定义路由
# 其余代码不变 urlpatterns = [ path('index/', views.index), path('tango', views.tango) ] 复制代码
启动应用,在浏览器中输入 http://127.0.0.1:8000/xray/tango/?team=seal
页面成功获取到响应,控制也成功输出了请求路径中携带的参数
当传入多个参数时 ?team=seal&location=Pakistan&count=6
,再通过上述的视图函数获取请求中的参数只能获取第一个
修改视图函数为如下形式:
def tango(request): request_param = request.GET print("保存多个请求参数的变量的数据类型是:{}".format(type(request_param))) print("请求中通过 `?` 传递的参数的值为: {}".format(request_param)) return HttpResponse('This is Tango 5, Do you read?') 复制代码
再次访问 ?team=seal&location=Pakistan&count=6
根据控制台的输出可以确定,多个参数会被保存成为一个查询字典,可以通过具体的 Key 来获取对应的 Value,接着就可以根据获取的参数进行各种逻辑处理了。
获取请求路径中的参数
在 xray 应用下的 views.py 中定义一个新的视图函数 yankee
,在该视图函数中定义一个参数用来接收请求路径中传递过来的参数。
def yankee(request, location): print('路径参数中的 location 变量的值为:{}'.format(location)) return HttpResponse('这是测试路径参数的页面') 复制代码
在 urls.py 中增加 yankee 视图函数对应的路由,在路由中定义路径参数的变量名和变量值类型。
urlpatterns = [ # 其余代码不变 path('yankee/<str:location>/', views.yankee), ] 复制代码
保存代码,浏览器访问 /xray/yankee/Pakistan/
控制台打印出路径中传递的参数 location 的值为 Pakistan
当路径中包含多个参数时,需要在视图函数中定义多个变量来接收请求路径中的参数,修改 yankee 视图函数
def yankee(request, location, num): print('路径参数中的 location 变量的值为:{}'.format(location)) print('路径参数中的 num 变量的值为:{}'.format(num)) return HttpResponse('这是测试路径参数的页面') 复制代码
修改 urls.py 中的路由,该路由中定义了传递的多个参数的参数名和参数类型
urlpatterns = [ # 其余代码不变 path('yankee/<str:location>/<int:num>', views.yankee), ] 复制代码
保存代码,浏览器访问 /xray/yankee/Pakistan/6/
控制台打印出路径参数中的 Pakistan 和 6