Django:URL 分发

一 URL配置

URL配置就像Django所支撑网站的目录,它的本质是URL与要为该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)

include URL 分发

在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 和URL反向解析

# 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>

 

posted @ 2020-08-03 14:03  muchen  阅读(200)  评论(0编辑  收藏  举报