13.Django之url路由系统初探(一)

  1. 云栖社区>
  2. 博客>
  3. 正文

13.Django之url路由系统初探(一)

技术小胖子 2017-11-22 14:54:00 浏览670
展开阅读全文

一、什么是django中的url路由系统?
django中的url路由系统的本质就是简历某个URL与某个视图(view)函数的对应(映射表)关系表,用下面这种特定的方式来告诉django这个web框架,哪个url可以去调用哪段python代码。

urls.py

    urlpatterns = [
     url(正则表达式, views视图函数,参数,别名),

]
正则表达式:一个用来表示正则表达式的字符串。
views视图函数:一般用来传一个可调用对象(视图函数)。
参数(可选):用来传递给视图函数的参数(字典形式)。

例:
from django.conf.urls import url
from . import views

urlpatterns=[
url(r'^datetime/',views.show_datetime),
url(r'^login/',views.auth_user),
url(r'^admin/',views.admin),
]

二、正则与url路由系统。
from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^test/2008/$', views.special_case_2008),
url(r'^test/([0-9]{4})/$', views.year_archive),
url(r'^test/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^test/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

下面来说下django url匹配的规则:
1.一旦匹配成功,则不会向下继续进行匹配。
2.若想从url中获取到参数,或者一个值,需要加括号()分组。
就像r'^test/([0-9]{4})/([0-9]{2})/$。
3.在匹配url的正则表达式中,不需要添加一个前置反斜杠!
例如:^test而不是/^test 。!!

下面是客户端向服务端发起请求的一些示例:
/test/2008/1/ 这种访问方式不会匹配任何到任何URL 规则,因为列表中的第三个模式要求月份应该是两个数字。

/test/2008/ 将会匹配到urls.py中urlpatterns的列表中的第一个url规则不是第二个,因为规则按顺序匹配,如果第一条规则成功匹配,则不再继续向下匹配了。

/test/2008/01/ 这个请求将匹配列表中的第三条规则。Django 将调用名为views.month_archive的视图函数,不过需要注意的是,2008和01则会当做参数,传入views.month_archive这个视图函数中。

三、url路由中正则的有名分组。
前面介绍的是比较简单的,没有命名的正则表达式,而是通过括号来捕捉url中用来传给视图函数的值。而命名分组是更高级的用法,通过使用命名的正则表达式来捕捉url中的关键字作为参数传递给视图函数。

在python这门语言中,命名正则表达式的写法是(?P<name>pattern)。
name指的是分组名称。
patterm指的是要匹配的正则表达式。

接下来我们使用分组正则表达式,将之前的url路由规则重写:
from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^test/2008/$', views.special_case_2008),
url(r'^test/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^test(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^test/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

这种使用分组正则表达式与之前的写法不同的是,从客户端请求url中捕捉到的关键值将作为关键字参数传给视图函数,而不是位置参数!!!!
例如:
/tesrt/2008/01/ 
请求将调用views.month_archive(request, year='2008', month='01')函数
/test/2008/01/01/ 
请求将调用函数views.article_detail(request, year='2008', month='01', day='01')。

django中的url路由系统是在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。

例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/。

在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找myapp/。

URL路由系统不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POST、GET、HEAD等等 —— 都将路由到相同的函数。
每个捕获的参数都作为一个普通的Python 字符串传递给视图,无论正则表达式使用的是什么匹配方式。

四.通过name参数来生成url路径。
通过name参数来生成指定的url!!!
url路由系统中的name参数,主要的作用是对URL路由关系进行命名,以后可以根据此名称通过reverse或者模板语言生成自己想要的URL。
下面是一个对name参数的使用示例:
from django.conf.urls import include,url
from django.contrib import admin

urlpatterns = [
url(r'^test/', views.index, name='url1'),
url(r'^main/(\d+)/(\d+)/', views.index, name='url2'),
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='url3'),
]
‘======================================================
#在上面的url路由系统中,一共有三条url规则,这三条url路由规则都使用了name参数进行了命名,首先我们先使用reverse函数来获取我们之前命名的url。
from django.urls import reverse 
#首先要先将reverse函数进行导入。
def url_test(request):
u1 = reverse('url1') #通过reverse函数去获取之前给url命名的名字。
u2 = reverse('url2',args=(1,2)) #通过reverse函数去获取以及生成url路径
u3 = reverse('url3',kwargs={'pid':'01','nid':'03'}) #通过reverse函数去获取以及生成url路径
return HttpResponse(u1)
#此时u1 = '/test/'
#u2 = '/main/1/2/'
#u3 = '/buy/01/03/'

同样的,这种通过name参数生成的url路径还可以在django的模板语言中实现,下面是模板语言生成url的示例:
{% url "i1" %} # test/
{% url "i2" 1 2 %} # main/1/2/
{% url "i3" pid=1 nid=2 %} # buy/1/2/

下面是一个url路径生成在模板中的应用实例:
(1)urls.py:
urlpatterns = [
url(r'^index',views.index,name='MAIN'),

]
下面是html代码以及form表单。
13.Django之url路由系统初探(一)

补:
1.在settings.py中,有一个参数可以用来设置开启或者关闭,当访问一个url地址后,是否跳转到带有/的url路径。
这个参数就是APPEND_SLASH = True 
(当APPEND_SLASH的值为True时,当客户端访问某个url后,自动跳转到url路由规则中的某个带有/的规则,为False则不会跳转。)
例1:
views.py
from django.conf.urls import url
from . import views

urlpatterns=[
url(r'^datetime/',views.show_datetime),
url(r'^login/',views.auth_user),
url(r'^admin/',views.admin),
]
这里有三条url规则。
当客户端的浏览器发起请求访问 http://127.0.0.1/datetime 这个url时,APPEND_SLASH = True 时会自动跳转到http://127.0.0.1/datetime/,
当APPEND_SLASH = False 时,则不会跳转,客户端访问的url依旧为http://127.0.0.1/datetime 。

2.url对应view中的默认参数示例:
from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

View (in blog/views.py)

def page(request, num="1"):

在上面的例子中,两个URL规则指向同一个视图views.page —— 但是第一个规则不会从URL 中捕获任何值。如果第一个规则匹配,page() 函数将使用num参数的默认值"1"。如果第二个模式匹配,page() 将使用正则表达式捕获的num 值!!

3.引入其他的url路由规则。

from django.conf.urls import include,url
from django.contrib import admin

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/',include('app01.urls'))
]

4.url路由 给view视图函数传递额外参数。
说的通俗一些,就是传递一个Python 字典作为额外的参数传递给视图函数。
django.conf.urls.url() 函数可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

例:
from django.conf.urls import url
from . import views

urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')。




      本文转自苏浩智 51CTO博客,原文链接:http://blog.51cto.com/suhaozhi/2044170,如需转载请自行联系原作者




网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注