Django中URL路由系统
url配置
1.url正则表达式和分组命名匹配:
urls.py
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'^$', views.home),
#匹配根路径 http://127.0.0.1:8000/
url(r'^book/(d+)/(d+)/', views.book),
# http://127.0.0.1:8000/book/2020/10
#分组正则,匹配到的数据传递给视图book函数
#无名分组正则:匹配到的数据以位置传参
url(r'^book/(?P<year>d+)/(?P<month>d+)/', views.book),
#有名分组正则:关键字传参
#写郑则时,别写冲突了,不然后面路径就失效了
]
views.py中视图函数写法:
from django.shortcuts import render, HttpResponse
def home(request):
return HttpResponse('hello world')
def book(request,year,month):
print(year,month) #year和month接收URL路径动态匹配到的数据,字符串数据类型
res = f"{year}-{month}-book"
return HttpResponse(res)
2.url别名和反向解析
urls.py
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 版本升级路径升级
# url(r'^home/', views.home,name='home'), #url设置别名,通过反向解析就可以得到前面'home/'路径
url(r'^home/v1/', views.home,name='home'), #前面路径无论怎么该,反向解析都能到这个页面
url(r'^login/', views.login),
url(r'^person/', views.person,name='person'),
]
views.py --后台逻辑反向解析 : reverse
from django.shortcuts import render,HttpResponse,redirect
from django.urls import reverse
# reverse 方向解析别名
def home(request):
return render(request,'home.html')
def login(request):
if request.method == 'GET':
print('首页路径>>',reverse('home')) #反向解析首页路径: 首页路径>> /home/
return render(request,'login.html')
else:
username = request.POST.get('username')
if username == 'jia':
# return redirect('/home/')
# return redirect(reverse('home')) #使用反向解析路径重定向页面
return redirect('home') #redirect内部自动会帮你进行reverse
else:
return render(request,'login.html')
templates目录下html文件
login.html
<body>
<form action="" method="post">
用户名:<input type="text" name="username">
<input type="submit">
</form>
</body>
home.html -- 反向解析url别名
<body>
<h1>首页</h1>
{# <a href="/person/">个人中心</a> #}
<a href="{% url 'person' %}">个人中心</a>
<!--通过模板渲染,使用url标签进行url别名反向解析 -->
</body>
person.html
<body>
<h1>个人中心页面</h1>
</body>
3.url命名空间
作用:
不同的APP使用相同的URL名称,你会发现,不管你是访问app01下的index还是app02下的index,打印的结果都是/app02/index/,也就是打印的是最后一个index别名对应的url路径。所以别名冲突了的话就需要我们的命名空间来保证别名对应的url的唯一性了。
三种方法,无论那种方法,反向解析语法都不变: '命名空间名称:URL名称'
第一种写法:
总路由: urls.py
from django.conf.urls import url, include
urlpatterns = [
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
# include 分发路由, namespace命名空间
]
app01新建urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'index', views.index, name='index')
]
app02新建urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'index', views.index, name='index')
]
现在,我的两个app中 url名称重复了,我反转URL的时候就可以通过命名空间的名称得到我当前的URL,
语法: --->'命名空间名称:URL名称'
views.py中的函数中反向解析
def index(request):
print(reverse('app01:index'))
return HttpResponse('ok')
html模板中反向解析
<a href="{% url 'app01:index'}">个人中心</a>
第二种写法:
就是在每个app下的urls.py文件中指定app名称,同样是命名空间
总路由 urls.py
from django.conf.urls import url,include
urlpatterns = [
url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls')),
]
app01新建的urls.py
from app01 import views
app_name = 'app01' #指定命名空间
urlpatterns = [
url(r'^index/', views.index,name='index'),
]
app02新建的urls.py
from app01 import views
app_name = 'app02' #指定命名空间
urlpatterns = [
url(r'^index/', views.index,name='index'),
]
views.py中的函数中反向解析
def index(request):
print(reverse('app01:index'))
return HttpResponse('ok')
html模板中反向解析
<a href="{% url 'app01:index'}">个人中心</a>
第三种写法:跟第一种差不多
总路由urls.py
from django.conf.urls import url,include
urlpatterns = [
# url(r'^app01/', include('app01.urls',namespace='app01')),#第一种写法
url(r'^app01/', include(('app01.urls','app01'),namespace='app01')),
url(r'^app02/', include(('app02.urls','app02'),namespace='app02')),
]
app01新建urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'index', views.index, name='index')
]
app02新建urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'index', views.index, name='index')
]