Django:URL 分发
# 基本格式 from django.conf.urls import url urlpartterns = [ url(正则表达式,views视图函数,参数,别名), ] # 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'^query/', views.query), ]
# 使用正则表达式 在URL中匹配路径
urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^app01/', views.index), url(r'^app01/$', views.index), url(r'^app01/([1,2]\d{3})', views.year),# 用括号将路径括起来,是用到分组匹配来捕获URL中的值,并以位置参数的形式传递给视图函数 ] # 当url(r'^app01/', views.index), # 在url中匹配到 app01 时就调用 views.index。后面的url不再匹配。所以无论app01路径后面还有没有子路径,都只会匹配 views.index ,urlpartterns 不会继续向下循环匹配了。 #所以 url(r'^app01/([1,2]\d{3})', views.year), 就永远不会被匹配到。 #解决办法:url(r'^app01/$', views.index), 将 app01/ 匹配规则写死。那么当url中"/app01/2012"就会被匹配到 views.year
# views.py def index(request): return render(request,'index.html') def year(request,year): return render(request,'year.html',{'year':year})
注意事项
1.urlpartterns中的元素按照书写顺序从上向下注意匹配,一旦匹配成功则不再继续 2.若要从url中捕获一个值,只需要在它周围使用 圆括号 将它括起来 3.不需要添加一个前导的反斜杠,因为每个URL都有。例如:正确写法'^app01/',错误写法'/^app01/' 4.每个正则表达式前面的 r ,是可选的,但是建议加上 5.'^app01/$',严格限制路径,这样就不会导致'^app01/([1,2]\d{3})'不会被匹配到了
使用分组命名匹配的正则表达式来捕获URL中的值,并以关键字参数的形式传递给视图函数 在python的正则表达式中,分组命名表达式的正确语法是(?P<name>parttern),其中name是组的名称,parttern是要匹配的正则表达式 URL的匹配位置。 URLconf在请求的URL上查找,将它当做一个普通的python字符串。不包括GET和POST以及域名 例如:http://127.0.0.1:8000/app01/2013/10/,URL将查找 app01/2013/10 需要注意的是,捕获的参数永远都是字符串。在每个URL中捕获的参数都作为一个普通的python字符串传递给视图
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/$', views.index), url(r'^app01/(?P<year>\d{4})$', views.year), url(r'^app01/(?P<year>\d{4})/(?P<month>(([0][1-9])|([1][0,1,2])))/$', views.year_month),# 这里用两个括号 括起来两个子路径,相当于捕获了两个参数,要传递给视图函数,而且给两个参数命名了,就相当于是关键字参数,那么视图函数中的参数名称必须与之对应 ] # views.py def index(request): return render(request,'index.html') def year(request,year): return render(request,'year.html',{'year':year}) def year_month(request,year='2010',month='01'):# 可以为参数指定默认值 return HttpResponse(year,month)
在Django项目中,项目本身有一个urls.py,项目中的所有应用都可以使用它,但是这样太难管理了,
尤其是当应用很多的时候,所以Django在url这里提供了一个分发接口,就是include
# 项目下的 urls.py from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^$', views.home), url(r'^app01/', include('app01.urls')), # url分发,当URL中匹配到app01时,就去app01中的urls.py中进行剩下的路径匹配 url(r'^app02/', include('app02.urls')),# 这里不能加$ 写成这样'^app02/$' ,会报错的 # app01.urls.py from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^$', views.index), url(r'^(?P<year>\d{4})$', views.year), # 这里会匹配app01/ 后面的路径, url(r'^(?P<year>\d{4})/(?P<month>(([0][1-9])|([1][0,1,2])))/$', views.year_month), ] # app02.urls.py from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^$', views.index), url(r'^login/', views.login), ]
# url 命名 from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^$', views.index,name='index'), # 给url匹配模式起别名为index,当别处引用别名时,只要别名不改,路径名随便改都不会影响别处的引用 url(r'^login/', views.login,name='login'), ] # 在模版中就可以按固定格式来引用:{% url 'login' %} <a href="{% url 'login' %}">click me</a> # 在.py 中函数里使用 return redirect(reverse('usrin'))
# app02 urls.py from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^$', views.index,name='index'), url(r'^login/', views.login,name='login'), url(r'^userinfo/', views.userinfo,name='usrin'), ] # app02 views.py from django.shortcuts import render,redirect from django.urls import reverse # Create your views here. def index(request): return render(request,'index02.html') def login(request): if request.method == 'GET': return render(request,'login.html') elif request.method == 'POST': print(request.POST) # return redirect('/app02/userinfo/') # 这里重定向需要写完整的路径 return redirect(reverse('usrin')) # 当使用url反向解析的时候,就很简单了,只要使用reverse(别名) def userinfo(request): return render(request,'userinfo.html') # index02.html <h1>this is app02 index page </h1> <a href="{% url 'login' %}">click me</a> # login.html <h1> this is app02 login page </h1> <form method="post"> {% csrf_token %} 用户名:<input type="text" name="username"> 密 码:<input type="password" name="password"> <input type="submit"> </form> # userinfo.html <h1> this is user info page </h1> <a href="{% url 'index' %}">返回首页</a>