03 Django--URL路由系统
URL路由系统
URL配置
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
基本格式:
from django.conf.urls import url
#循环urlpatterns,找到对应的函数执行,匹配上一个路径就找到对应的函数执行,就不再往下循环了,并给函数传一个参数request,和wsgiref的environ类似,就是请求信息的所有内容
urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]
参数说明
- 正则表达式:一个正则表达式字符串
- views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
- 参数:可选的要传递给视图函数的默认参数(字典形式)
- 别名:一个可选的name参数
正则表达式
示例:查找年份、月份对应的文章。效果显示:输入http://127.0.0.1:8000/articles/2019/9/
urls基本配置
无名与有名分组。
分组命名正则表达式组的语法是(?P<name>pattern)
,其中name
是组的名称,pattern
是要匹配的模式。
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [url(r'^admin/', admin.site.urls),
url(r'^home/', views.home),
#路径分发 不区别请求方法
url(r'^login/', views.login),
# 无名分组参数articles会携带两个分组的位置参数,一一对应
# url(r'^articles/(\d+)/(\d+)/', views.articles),
# 有名分组参数articles会携带两个分组的关键字参数
url(r'^articles/(?P<y>\d+)/(?P<m>\d+)/', views.articles),]
views视图
在视图函数中可以指定默认值。
from django.shortcuts import render, HttpResponse
# Create your views here.
def home(request):
print(request.path)
# return HttpResponse('hahaha') # 返回字符串
return render(request,'home.html') # 返回html文件
def login(request):
if request.method == 'POST':
print(request.POST)
# <QueryDict: {'username': ['yan'], 'pwd': ['123']}>
name = request.POST.get('username')
pwd = request.POST.get('pwd')
if name == 'yan' and pwd == '123':
return HttpResponse('登录成功!')
else:
return HttpResponse('登录失败!')
else:
return render(request, 'login.html')
# 无名匹配分组执行的函数,是位置参数
# def articles(request,year,month):
# print(year,month) # 获取到year="2019" month="9"
# return HttpResponse(year+'年'+month+'月所有文章!')
# 有名匹配分组执行的函数,是关键字参数
def articles(request,m,y):
print(y, m) # 获取到y="2019" m="9"
return HttpResponse(y + '年' + m +'月所有文章!')
注意事项
- urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
- 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
- 不需要添加一个前导的反斜杠(也就是写在正则最前面的那个/),因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
- 每个正则表达式前面的'r' 是可选的但是建议加上。
- ^articles& 以什么结尾,以什么开头,严格限制路径。
捕获的参数永远都是字符串:
每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。(数字也是字符串类型)
login.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>24期官网</h1>
<form action="/login/" method="post">
<!-- http://127.0.0.1:8000/login/ /login/前面的/代表根目录 -->
<!-- 如果不加前面的 / http://127.0.0.1:8000/login/login/ -->
用户名:<input type="text" name="username">
密码:<input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
include--URL分发
- python manage.py startapp app02 # 增加一个应用,并在setting中配置
- 在app01、app02等文件夹下创建urls.py文件,配置本应用的路径
- 在项目目录下的ulrs.py文件引入include,完成以下配置
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^app01',include('app01.urls')),
# http://127.0.0.1:8000/app01/xxx 只要匹配到app01,就会去app01.urls文件下匹配 xxx
url(r'^app02',include('app02.urls')),
url(r'^$', views.base) # 首页 不加任何路径,只有 127.0.0.1:8000
]
命名URL(别名)和URL的反向解析
在urls.py文件中:
url(r'^路径/', views.函数名, name='别名'),
例如:
url(r'^home2', views.home, name='home'),
在html文件模板中:
多用于a、form表单。
{% url '别名' %}
例如:
{% url 'home' %} # /home2/
views.py
可用于重定向
from django.urls import reverse
reverse('别名') # 反向解析
例如:
reverse("home") # /home2/
def my_url(request):
return redirect('别名') # 直接写别名,不用reverse
如果在include路由分发的时候使用别名,会在reverse时发生路径的错误。因此需要进行命名空间模式的设置。
命名空间模式
即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。
url(r'^app01',include('app01.urls', namespace='app01')),
# 反向解析
reverse('app01:home') # 命名空间名称:别名
html文件中:
{% url '命名空间名称:别名' %}