URL-统一资源定位符(Uniform Resource Locator)用来表示互联网某个资源的地址,类比理解为windows下某个文件的路径。URL的一般语法格式为(注:[]代表其中的内容可省略)
proptcol://hostname[:port]/path/[?query][#fragment]
http://tts.tmooc.cn/video/showVideo?menuId=657421&version=AID999#subject
这里的web端口为80,path就是路由,?key=value为查询字符串,因此?是一个很重要的表示;#之后的部分为锚点,所谓的锚点就是上一次出现的位置,比如:https://docs.djangoproject.com/zh-hans/2.2/ 点击锚点跳转到:https://docs.djangoproject.com/zh-hans/2.2/#the-model-layer ,从该链接跳转可以继续回到原来的快速入门这里,类似一个书签的原理。
1.Django处理url
浏览器输入:http://127.0.0.1:8000/page/2003为例
- Django首先根据settings.py中的ROOT_URLCONF中到主路由文件,默认情况下,该文件在项目同名目录下的urls.py中,例如mysite/mysite/urls.py
- Django加载主路由文件中的urlpatterns变量
- 依次匹配urlpatterns中的path,注意是从上往下匹配,匹配到第一个合适的路由中断后续匹配
- 匹配成功,调用对应的视图函数处理请求返回响应
- 匹配失败,提示404报错
这里创建一个Django的项目,配置环境为: Windows10 64位 Python36 Django2.2.12
创建一个mysite1的项目
F:\Django\DjangoStudy>django-admin startproject mysite1
进入到项目同名文件下的settings.py中先设置为中国时间和汉语展示,在settings.py中
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
这里假设我们要访问如下地址,在项目同名文件夹mysite1二级目录下的urls.py中,新增一个path(‘page/2021…’)
urlpatterns = [
path('admin/', admin.site.urls),
path('page/2021',views.page_2021)
]
此时需要匹配一个视图函数,views.page_2021,那什么是视图函数呢?
2.视图函数
视图函数是一个用于接收浏览器请求(HttpRequest对象)并通过HttpResponse对象返回响应的函数。此函数可以接收浏览器请求并根据业务逻辑返回相应的响应内容给浏览器,其定义一般如下所示
def XXX_views(**request** [,args]):
return HttpResponse对象
因此在二级目录的mysite1下新增一个views.py文件
from django.http import HttpResponse
def page_2021(request):
html = "<h1>这是第一个页面</h1>"
return HttpResponse(html)
接着在项目同名文件夹下的urls.py的urlpattern中引入上文新建的views视图包
from mysite1 import views
在项目目录下运行:
python mange.py runserver
在浏览器中输入: http://127.0.0.1:8000/page/2021。输出结果如下所示: 上面的整体有了初步认识之后,这里详细介绍下,路由的使用
3.路由配置
使用path()函数,在urls.py文件中需要导入
from django.urls import path
path(route,views,name)
- route字符串类型,请求的路径
- views指定路径所对应的视图函数的名称,这里注意是是函数名称,没有函数后的()
- name为地址起一个别名,在模板地址反向解析的时候使用
有了上述的知识体系,这里我们继续做如下的网址访问 浏览器地址输入http:127.0.0.1:8000 界面展示这是我的首页 浏览器地址输入http:127.0.0.1:8000/page/1,界面展示这是我的第一个界面 浏览器地址输入http:127.0.0.1:8000/page/2,界面展示这是我的第二个界面
在urls.py的url_pattern中新增如下配置
path('',views.index_view),
path('page/1',views.page1_view),
path('page/2',views.page2_view),
在views.py中新增相对应的视图函数
def index_view(request):
html = "这是我的首页"
return HttpResponse(html)
def page1_view(request):
html = "这是我的第1个页面"
return HttpResponse(html)
def page2_view(request):
html = "这是我的第2个页面"
return HttpResponse(html)
结果展示如下所示: 上面输出了第一个页面和第二个页面,如果是要输出第3,4,…N个页面,如何处理呢?
4.path转换器
4.1 path转换器介绍
语法:<转换器类型:自定义名> 说明:若转换器匹配到对应类型的数据,则将数据安装关键字传参的方式传递给视图函数 ex:path(‘page/int:PageNumber’,views.xxx) 转换器的类型包括:str,int,slug,path 在url.py中的url_pattern中新增
path('page/<int:pageNumber>',views.pagen_view),
在视图函数中
def pagen_view(request,pageNumber):
html = "这是我的第%s个页面"%(pageNumber)
return HttpResponse(html)
注意:url_pattern中是从上往下匹配的,因此上文的中page/1路由实际匹配的path(‘page/1’,views.page1_view),而page/3匹配的是path(‘page/int:pageNumber’,views.pagen_view)
4.2 path转换器示例
定义一个路由格式为http://127.0.0.1:8000/整数/操作字符串[add/sub/mul]/整数,从路由中提取数据,做相应的结果展示为浏览器 ex:http://127.0.0.1:8000/10/add/20 views逻辑运算为10 add 20 = 30,浏览器展示为30 在urls.py中新增路由
path('<int:m>/<str:cal>/<int:n>',views.cal_view)
在视图函数中新增视图函数
def cal_view(request,m,cal,n):
if cal not in ['add','sub','mul']:
return HttpResponse("输入有误")
result = 0
if cal=="add":
result = m + n
elif cal == 'sub':
result = m - n
elif cal == 'mul':
result = m * n
html = "输出结果为:%s" % (result)
return HttpResponse(html)
输出结果为: 接着对上的实例进行优化,比如我们要求只能计算2位数以内的运算,如何做限制,这种对于指定格式的字符串进行提取,理解就想到了python中的正则表达式,这里path中有re_path
4.3 re_path
re_path(reg,view,name=xxx) 这里的reg有自己的格式要求,必须采用命名分组的形式,(?Ppattern),匹配提取参数后用关键字传参方式传递给视图函数,安装上面的需求,进行两位数以内的运算,比如: http://127.0.0.1:8000/20/add/99 这种就可以进行运算 http://127.0.0.1:8000/200/add/1这种就不能运算
继续首先在url.py中urlpatterns配置一个路由
from django.urls import re_path
re_path(r'^(?P<m>\d{1,2})/(?P<cal>\w+)/(?P<n>\d{1,2})',views.cal2_view),
path('<int:m>/<str:cal>/<int:n>',views.cal_view),
在视图函数中新增cal2_view新增视图函数逻辑
def cal2_view(request,m,cal,n):
if cal not in ['add','sub','mul']:
return HttpResponse("输入有误")
result = 0
m, n = int(m),int(n)
if cal=="add":
result = m + n
elif cal == 'sub':
result = m - n
elif cal == 'mul':
result = m * n
html = "使用cal2_view输出结果为:%s" % (result)
return HttpResponse(html)
注意:无论是path还是re_path,都提到了用关键字传递参数的方式进行传递,因此这里是url中分组名字的参数名称一定要和views.py中的参数列表中的命名一致,这里的关键传参,虽然形式和python中传递参数一样,但是这里实际不同,必须是根据命名将参数传递到view中。如何理解呢 比如希望输出一个人的生日 http://127.0.0.1:8000/birthday/2021/01/02 http://127.0.0.1:8000/bidthday/01/02/2021
上面两种方式都输出生日为2021年1月2号 urls.py中新增路由配置
re_path(r'^birthday/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})$',views.birth_view),
re_path(r'^birthday/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<year>\d{4})$',views.birth_view),
views.py中新增视图函数
def birth_view(request,year,month,day):
html = "生日是%s年%s月%s日"%(year,month,day)
return HttpResponse(html)
我们注意到传递的参数都是year,month,day,但是并不是安装Python函数传递参数从左到右进行匹配
|