一、路由系统基本格式:
urlpatterns = [path( 要匹配的路径(可以是正则表达式), 视图函数, 参数, 别名)]
参数说明:
- 正则表达式:一个正则表达式字符串
- 视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串。
- 参数:要传递给视图函数的默认参数(字典形式,)
- 别名:url反向代理
django的路由系统作用:
使views里面处理数据的视图函数(类)与请求的url建立映射关系。使请求到来之后,根据urls.py里的关系条目,去查找到与请求对应的处理方法,从而返回给客户端http页面数据。
二、正则表达式详解
- 在python中使用 re_path模块来写正则表达式
from django.urls import re_path
正则表达式的格式:r'^xxxx/$'
- 正则表达式的开始使用“^”表示。
- 正则表达式的结束使用“$”表示。
- “r” 元字符串 防止正则表达式中的转义。
一些常用的正则表达
- [a-zA-Z]表示匹配所有英文字母中的任意一个字母
- [0-9]表示任意一个数字
- \d+表示前面的数字,出现一次或者多次
- [0-9]{4}表示数字需要出现4次
最基础的URL映射
- 先从创建的app下的views.py面定义处理数据的函数
- 在urls.py里导入views
- 在urlpatterns里写入一条url与处理函数的l映射关系
- url映射一般是一条正则表达式,“^” 字符串的开始,“$“ 字符串的结束
- 当写成”^$“时,不输入任何url时不会在返回黄页,而是返回后面函数里对应的页面。一般这一条会写在url的最后。如:
url(r'^$', views.index),
urls.py 文件
from django.contrib import admin
from django.urls import path,re_path
from demo01 import views
urlpatterns = [
re_path(r'^lawang4/$',views.laowang4),#匹配laowang4/路径
re_path(r'$',views.laowang5),#匹配空路径 例如: http://127.0.0.1:8000
re_path(r'lawang6/',views.laowang6),#不设置结尾,可以匹配多个路径 例如: http://127.0.0.1:8000/ee//egg
re_path(r'[a-zA-Z][0-9]/$',views.laowang7)
#[a-zA-Z]表示匹配所有英文字母中的任意一个字母
] #[0-9]表示任意一个数字
views.py 文件
from django.shortcuts import render
#初始 正则
def laowang4(request):
return render(request,'laowang4.html')
#匹配空路径
def laowang5(request):
return render(request,'laowang5.html')
#匹配多个路径
def laowang6(request):
return render(request,'laowang6.html')
#模糊匹配
def laowang7(request):
return render(request,'laowang7.html')
三、正则表达式分组及分组命名匹配
1.正则分组匹配:
格式:(正则内容)
正则表达式分组匹配是通过小括号”()”来捕获URL中的值并以位置参数形式传递给对应视图函数的位置参数。
视图函数接受的是内容时字符串类型。
urls.py
文件
re_path(r'^laowang8/(\d+)/$',views.laowang8),
views.py
文件
def laowang8(request,num):
print(num)
return render(request,'laowang8.html')
2. 正则分组命名匹配:
分组命名正则表达式组的语法
(?P<name> pattern)
其中:
- name是组的名称
- pattern是要匹配的模式(正则内容)。
匹配成功后会将内容以关键词参数传递给对应的是视图函数,因此,视图函数的形参命名必须和正则分组匹配的’<名称>'相同。和先后顺序无关。
捕获的值作为 关键字参数 而不是位置参数传递给视图函数。
urls.py
文件
re_path(r'^laowang9/(?P<year>[0-9]{4})/$',views.laowang9),
re_path(r'^laowang10/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.laowang10),
views.py
文件
def laowang9(request,year):
print(year)
return render(request,'laowang9.html')
def laowang10(request,month,year):
print(month)
return render(request,'laowang10.html')
四、视图函数中指定默认值
如果匹配成功,则覆盖默认值,使用传递过来的值。
如果不能匹配成功,则使用默认值。
urls.py
文件
re_path(r'^laowang11/(?P<year>[0-9]{4})/$',views.laowang11),
views.py
文件
def laowang11(request,year='2019'):
return render(request,'laowang11.html',{'year':year})
其中 year='2019
是指定的默认值
五、传递额外参数给视图函数
路由系统的第三个参数(字典参数)
字典的key必须和视图函数中的形参相同,否则报错
urls.py
文件:
re_path(r'^laowang12/(?P<month>[0-9]{2})/$',views.laowang12,{'year':'2019'}),
其中:{'year':'2019'}
给的额外参数,值必须是字符串。
views.py
文件:
def laowang12(request,year,month):
return render(request,'laowang12.html',{'year':year,'month':month})
其中:year
必须和字典的key
对应。
六、Url反向代理(别名)
- 解决的问题: 程序中硬编码的问题。
下面就使用反向代理和没有使用反向代理的 区别进行比较:
- 当没有使用反向代理的时候:
urls.py
文件:
re_path(r'^laowang13/$',views.laowang13),
re_path(r'^laowang14/$',views.laowang14),
views.py
文件:
def laowang13(request):
return render(request,'laowang13.html')
def laowang14(request):
return render(request,'laowang14.html')
laowang13的html.py
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/laowang14/">点我14</a>
<br>
- 使用反向代理
urls.py
文件:
re_path(r'^laowang13/$',views.laowang13),
re_path(r'^laowang141/$',views.laowang14,name='lw14'),
其中:name='lw14'
就是反向代理
views.py
文件:
def laowang13(request):
return render(request,'laowang13.html')
def laowang14(request):
return render(request,'laowang14.html')
laowang13的html.py
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
老王13 <br>
<a href="/laowang14/">转跳到laowang14页面</a>
<br>
<a href="{% url 'lw14' %}">转跳到laowang14页面</a>
</body>
</html>
当把re_path(r'^laowang141/$',views.laowang14,name='lw14'),
中的laowang14
改成laowang141
使用反向代理还是可以访问laowang14.html
七、Url反向解析带参数
- 格式:
name=’xxx’
。 - 页面中使用反向代理: {%url ‘别名名称’ %}
- 如果传递参数:{%url ‘别名名称’ 参数1 参数2 … %}
其中:参数要用字符串:
urls.py
文件:
re_path(r'^laowang13/$',views.laowang13),
re_path(r'^laowang15/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.laowang15,name='lw15'),
views.py
文件:
def laowang13(request):
return render(request,'laowang14.html')
def laowang15(request,year,month):
return render(request,'laowang15.html')
laowang13的html.py
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/laowang15/2019/11/">跳转到老王15页面</a>
<br>
<a href="{% url 'lw15' '2018' '12' %}">跳转到老王15页面</a>
</body>
</html>
如上图:标出的是解析带参数