param方式:通过url加?的链接所使用的就是param传参,例如http://127.0.0.1:8000/book?book_id=1 所使用的就是param进行传参,
此时的参数就是一个{'id':1}这样的字典。
path方式:例如http://127.0.0.1/book/2 这样的方式就是path传参。
为了更好的理解Django中这两种传参方式的特征,我们将通过编写对应的url和视图进行更加直观说明。
9.1 通过param进行参数的传递
首先,在我们项目的urls.py中编写如下的内容。
from django.urls import path
from book import views as v1 # 从book这个app中导入视图函数views并重命名为v1
urlpatterns = [
path('book/', v1.book_param) # 前面没有/ 是因为Django会自动在前面添加一个/
]
编写好路由后,在到book(可以定义为其他的,我这里用的是book)这个app中,编写对应的视图也就是views.py
from django.shortcuts import render, HttpResponse
def book_param(request):
book_id = request.GET.get("id")
return HttpResponse(f"通过param传递的book_id是:{book_id}")
此时运行我们的项目,并访问http://127.0.0.1:8000/book?id=<book_id>&..., 其中<book_id>可以是任意值,&后面也可以跟任意内容。
例如下面这几种方式:
http://127.0.0.1:8000/book?id=1 # 通过param传递的book_id是:1 http://127.0.0.1:8000/book?id=2 # 通过param传递的book_id是:2 http://127.0.0.1:8000/book?id=2&why=5 # 通过param传递的book_id是:2 http://127.0.0.1:8000/book?id=2&why=6&wt=7 # 通过param传递的book_id是:2
param中&的作用
&用来分割不同的内容块,我们使用request.GET可以获取到对应的param参数,如果我们打印request.GET可以发现,这个内容是一个字典。
以http://127.0.0.1:8000/book?id=2&why=6&wt=7 ,以这个链接为例,首先获取?后面的部分(也就是param参数内容)
然后通过&分割为id=2、why=6、wt=7三块内容,再通过=来划分出对应的key和value,此时就可以得到
{"id":2, "why":6, "wt":7}这样的一个字典了。
为了更加直观的感受这个内容,我们同样编写一个新的url和视图。
# urls.py
from django.urls import path
from book import views as v1 # 从book这个app中导入视图函数views并重命名为v1
urlpatterns = [
path('book/', v1.book_param), # 前面没有/ 是因为Django会自动在前面添加一个/
path('book/request', v1.book_param_request())
]
# book.views.py
from django.shortcuts import render, HttpResponse
def book_param_request(request):
print(request.GET)
return HttpResponse(request.GET)
def book_param(request):
book_id = request.GET.get("id")
return HttpResponse(f"通过param传递的book_id是:{book_id}")
此时可以运行我们的项目,访问http://127.0.0.1:8000/book/request?id=2&why=6&wt=7 ,得到的页面应该是这样的:
9.2 通过path传递参数
在Django的路由中我们可以通过<>尖括号的方式来捕获我们所需要的内容。
# urls
from django.urls import path
from book import views as v1 # 从book这个app中导入视图函数views并重命名为v1
urlpatterns = [
path('book/<book_id>', v1.book_path_one),
path('book/<int:book_id>/<str:name>', v1.book_path_two)
]
# book.views.py
from django.shortcuts import render, HttpResponse
def book_path_one(request, book_id):
return HttpResponse(f"通过path传递的book_id是:{book_id}")
def book_path_two(request, book_id, name):
return HttpResponse(f"通过param传递的book_id是:{book_id}, name是:{name}")
此时可以猜测一下,以下这七个链接都有那些会报错404:
答案是:
(2),(4),(6),(7)这四个链接会报错
原因分析
在分析原因之前,我们首先要了解book/<book_id>和book/<int:book_id>/<str:name>究竟实现了怎样的匹配。\
先来说
book/<book_id>,由于我们并没有想后面那样在<>内设置参数类型,默认使用的就是str类型。
这个类型的一个特征就是:匹配任意内容,但是不包括/。
通俗来说就是能够匹配两个/之间的任意内容,所以我们可以看到,第(2)条链接是错的,而第(3)个链接是对的,原因就在与第二条链接中多了一个/,而我们只能匹配成功http://127.0.0.1:8000/book/req,但是因为最后有一个/的存在,Django判定的是不属于http://127.0.0.1:8000/book/req,所以导致Django找到这个url对应的视图。
之后我们再来分析
book/<int:book_id>/<str:name>,由于我们指定了book_id的类型,是int类型,这也就以为着,/book/xx, 这个xx只能是数字,而不能是其他任何内容,/book/xx/yy 而yy可以是任意内容,但是不能出现/
所以自然我们也就能知道为什么(4)、(6)、(7)出错了,第四个是因为xx不是数字,而六则是因为多了一个/,七则是path中多了一节