Django路由
路由匹配
- 路由: 通俗理解为取出ip和port之后的地址
在新版本Django2.X中,url的路由表示用path和re_path代替:
模块导入由django1.X版本的from django.conf.urls import url,include变成了现在的from django.urls import path,re_path,include
django提供了两种设计url的方法: path和re_path,他们均支持向视图函数或类传递参数。path是正常参数传递,re_path是采用正则表达式regex匹配:
- path方法:采用双尖括号<变量类型:变量名>或者<变量名>传递,例如int:id
- re_path方法:采用命名组(?P<变量名>表达式)的方法传递参数
- path支持匹配的数据类型只有str,int,slug,uuid四种,一般来说re_path更强大,但写起来更复杂
'''urls.py'''
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'test',views.test),
re_path(r'testadd',views.testadd),
]
'''views.py'''
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def test(request):
return HttpResponse('from test')
def testadd(request):
return HttpResponse('from testadd')
'''
这样很明显,无论是test还是testadd匹配的都是from test,所以在路由中,应该在末尾加个/
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^test/',views.test),
re_path(r'^testadd/',views.testadd),
]
'''
- Django特性; 如果在url后面路径没有写/,那么会自动补充/,相当于跳转了页面,如果不想使用该特性,可以在配置文件中取消:APPEND_SLASH = False

下面一个例子,我们分别用path和re_path定义两个url,他们是等效的,把文章的id(整数类型)传递给了视图。re_path里引号前面的小写r表示引号里为正则表达式,^代表了开头,$代表了结尾,/d+代表了多位整数
urlpatterns = [
# path('admin/', admin.site.urls),
# re_path(r'^test/',views.test),
# re_path(r'^testadd/',views.testadd),
path('articles/<int:id>/',views.article_detail,name='article_detail'),
re_path(r'^articles/(?P<id>\d+)/$',views.article_detail,name='article_detail'),
]
'''views.py'''
def article_detail(request,id):
return HttpResponse('from article_detail')
在使用path和re_path方法设计urls需要注意
- url中的参数要用尖括号,而不是圆括号
- 匹配模式的最开头不需要加斜杠/,但是建议末尾加
- 使用re_path的时候,不一定总以$结尾,有时可以不加
无名分组
涉及到urls.py写对应关系,无名分组后如果不给视图函数传参,那么就会报错
通俗的理解:路由使用正则,正则匹配加括号分组,当做了视图函数的第二个位置参数
'''urls.py'''
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 匹配数字
# re_path(r'^test/[0-9]{4}/$',views.test),
# 无名分组,匹配1个到多个正整数
re_path(r'^test/(\d+)/$',views.test),
]
'''views.py'''
def test(request,num):
print(num) # 1234
return HttpResponse('from test')
'''路由使用正则,正则匹配加括号分组,当作了视图函数的第二个位置参数'''
有名分组
在使用路由的时候,正则表达式可以起别名,别名当做关键字参数传给视图函数
'''urls.py'''
urlpatterns = [
re_path(r'^test/(?P<id>\d+)/$',views.test),
]
'''views.py'''
def test(request,id):
print(id)
return HttpResponse('from test')
# 有名分组,将匹配到的数字命名成id,当成关键字参数传给视图函数
- 无名分组与有名分组是不能混合使用的
re_path(r'^test/(\d+)/(?P<id>\d+)/$',views.test)
def test(request,a,id):
print(a,id)
return HttpResponse('from test')
# 这样不可以
- 相同类型的分组是可以混用的
re_path(r'^testadd/(\d+)/(\d+)/$',views.testadd)
def testadd(request,*args,**kwargs):
return HttpResponse('from testadd')
# 这样使用相同分组是可以的
反向解析
反向解析解决了当路由频繁变化的时候,html界面上的连接地址实现动态解析;
'''urls.py'''
# 1、给路由与视图函数对应关系添加一个别名
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 反向解析
path('index/',views.index,name='index_name'),
path('home/',views.home)
]
'''views.py'''
from django.shortcuts import HttpResponse,render,reverse
def index(request):
return HttpResponse('from index')
def home(request):
print(reverse('index_name'))
# 或者
# return redirect('index_name')
return render(request,'home.html')
'''home.html'''
<a href="{% url 'index_name' %}">111</a>
<a href="{% url 'index_name' %}">111</a>
<a href="{% url 'index_name' %}">111</a>
# 总结
当路由频繁变化的时候,html界面上的连接地址如何做到动态解析
# 1.给路由与视图函数对应关系添加别名(名字自己指定,只要不发生冲突即可
path('index/',views.index,name='index_name')
# 2.根据该别名动态解析出一个结果,该结果可以直接访问到对应的路由
前端
<a href="{% url 'index_name' %}">111</a>
后端
redirect('index_name') # <HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/index/">
无名分组和有名分组的反向解析
如果有分组情况,不写参数会报错的
- 无名分组反向解析
# 无名分组
1、起别名
re_path(r'^index/(\d+)/',views.index,name='index_name')
2、前端
<a href="{% url 'index_name' 1 %}"></a> # 只要给个数字即可
3、后端
reverse('index_name',args=(1,)) # 只要给个数字即可
- 有名分组反向解析
# 无名分组
1、起别名
re_path(r'^index/(?P<id>\d+)/',views.index,name='index_name')
2、前端
<a href="{% url 'index_name' id=1 %}"></a> # 只要给个数字即可
3、后端
reverse('index_name',kwargs={'id':1}) # 只要给个数字即可
- 总结
- 再次验证了,分组对应传的参数,无名对应位置参数,有名对应关键字参数
- 需要注意的是django2.X版本的变化,用的是path和re_path写路由,而django1.X版本用的是url写路由,在前端页面写反向爱那估计诶下的时候用的是url
- 上面的参数用数字代替,在实际应用中经常使用数据主键值(视图函数的参数)
def index(request,id): return render(request,'home.html') # id一般是获取到的主键值

浙公网安备 33010602011771号