Django 路由控制的实现

  • 时间:
  • 浏览:21

1 Django中路由的做用

URL设置装备摆设(URLconf)便像Django 所支持网站的目次。它的素质是URL取要为该URL挪用的视图函数之间的映照表;您便是以这类体例告知Django,对客户端收去的某个URL挪用哪1段逻辑代码对应履行

典范的例子:

from django.urls import path

urlpatterns = [
  path('articles', views.special),
]

articles那个路由对应着视图函数中special那个办法,阅读器输出那个链接,便会呼应到special那个函数去履行

URL设置装备摆设(URLconf)便像Django 所支持网站的目次。它的素质是URL取要为该URL挪用的视图函数之间的映照表;您便是以这类体例告知Django,对那个URL挪用那段代码,对阿谁URL挪用那段代码。

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

参数申明:

    1个正则表达式字符串
    1个可挪用工具,凡是为1个视图函数或1个指定视图函数途径的字符串
    可选的要通报给视图函数的默许参数(字典情势)
    1个可选的name参数

2 简朴的路由设置装备摆设

from django.urls import path,re_path

from app01 import views

urlpatterns = [
  re_path(r'^articles/2003/$', views.special_case_2003),
  re_path(r'^articles/([0⑼]{4})/$', views.year_archive),
  re_path(r'^articles/([0⑼]{4})/([0⑼]{2})/$', views.month_archive),
  re_path(r'^articles/([0⑼]{4})/([0⑼]{2})/([0⑼]+)/$', views.article_detail),
]

留意:

  • 若要从URL 中捕捉1个值,只需求正在它四周安排1对圆括号。
  • 没有需求增加1个前导的反斜杠,由于每一个URL 皆有。比方,应当是^articles 而没有是 ^/articles。
  • 每一个正则表达式后面的'r' 是可选的可是倡议减上。它告知Python 那个字符串是“本初的” —— 字符串中任何字符皆不该该本义

示例:

 1些要求的例子:

  • /articles/2005/03/ 要求将婚配列表中的第3个形式。Django 将挪用函数views.month_archive(request, '2005', '03')。
  • /articles/2005/3/ 没有婚配任何URL 形式,由于列表中的第3个形式请求月份应当是两个数字。
  • /articles/2003/ 将婚配列表中的第1个形式没有是第2个,由于形式按挨次婚配,第1个会起首测试是不是婚配。请像如许自在拔出1些特别的状况去探测婚配的序次。
  • /articles/2003 没有婚配任何1个形式,由于每一个形式请求URL 以1个反斜线末端。

/articles/2003/03/03/ 将婚配最初1个形式。Django 将挪用函数views.article_detail(request, '2003', '03', '03')。

3 着名分组

下面的示例利用简朴的、出有定名的正则表达式组(经由过程圆括号)去捕捉URL 中的值并以地位 参数通报给视图。正在更初级的用法中,可使用定名的正则表达式组去捕捉URL 中的值并以枢纽字 参数通报给视图。

正在Python 正则表达式中,定名正则表达式组的语法是(?Ppattern),此中name 是组的称号,pattern 是要婚配的形式。

上面是以上URLconf 利用定名组的重写:

from django.urls import path,re_path

from app01 import views

urlpatterns = [
  re_path(r'^articles/2003/$', views.special_case_2003),
  re_path(r'^articles/(?P[0⑼]{4})/$', views.year_archive),
  re_path(r'^articles/(?P[0⑼]{4})/(?P[0⑼]{2})/$', views.month_archive),
  re_path(r'^articles/(?P[0⑼]{4})/(?P[0⑼]{2})/(?P[0⑼]{2})/$', views.article_detail),
]

那个真现取后面的示例完整不异,只要1个纤细的不同:捕捉的值做为枢纽字参数而没有是地位参数通报给视图函数。比方:

  •     /articles/2005/03/ 要求将挪用views.month_archive(request, year='2005', month='03')函数,而没有是views.month_archive(request, '2005', '03')。
  •     /articles/2003/03/03/ 要求将挪用函数views.article_detail(request, year='2003', month='03', day='03')。

正在现实利用中,那意味您的URLconf 会愈加了了且没有简单发生参数挨次成绩的毛病 —— 您能够正在您的视图函数界说中从头摆设参数的挨次。固然,那些益处是以简约为价格;

4 路由分收

#主urls
from django.urls import path,re_path,include
from app01 import views

urlpatterns = [

  # re_path(r'^app01/',include('app01.urls')),#止
  # re_path(r'^app01/&',include('app01.urls')),#不可
  # path('app01/',include('app01.urls')),#止
  # path('app01',include('app01.urls')),#不可
]

正在app01里创立1个urls

from django.urls import path,re_path
from app01 import views
urlpatterns = [
  re_path(r'^test/(?P[0⑼]{2})/$',views.url_test),
]

5 反背剖析

正在利用Django 项目时,1个罕见的需供是取得URL 的终究情势,以用于嵌进到死成的内容中(视图中战显现给用户的URL等)或用于处置办事器真个导航(重定背等)。人们激烈期望没有要硬编码那些URL(吃力、不成扩大且简单发生毛病)或设想1种取URLconf 绝不相干的特地的URL 死成机造,由于如许简单致使1定水平上发生过时的URL。

正在需求URL 的处所,对差别层级,Django 供给差别的东西用于URL 反查:

  • 正在模板中:利用url 模板标签。
  • 正在Python 代码中:利用from django.urls import reverse()函数

urls.py

from django.urls import path,re_path
from app01 import views
urlpatterns = [
  re_path(r'^test/(?P[0⑼]{2})/(?P[0⑼]{2})/$',views.url_test,name='test'),
]

html

视图函数中:

from django.shortcuts import render, HttpResponse,redirect,reverse
def url_test(request,year,month):
  print(year)
  print(month)
  url=reverse('test',args=(10,20))
  print(url)
  return HttpResponse('ok')

总结:1 正在html代码里{% url "别号" 参数  参数%}

   2 正在视图函数中:

    2.1 url=reverse('test')

    2.2 url=reverse('test',args=(10,20))

当定名您的URL 形式时,请确保利用的称号没有会取别的利用中称号抵触。若是您的URL 形式叫做comment,而别的1个利用中也有1个一样的称号,当您正在模板中利用那个称号的时分不克不及包管将拔出哪一个URL。正在URL 称号中减上1个前缀,好比利用的称号,将削减抵触的能够。我们倡议利用myapp-comment 而没有是comment。

6 称号空间

定名空间(英语:Namespace)是暗示标识符的可睹范畴。1个标识符可正在多个定名空间中界说,它正在差别定名空间中的寄义是互没有相关的。如许,正在1个新的定名空间中可界说任何标识符,它们没有会取任何已有的标识符产生抵触,由于已有的界说皆处于别的定名空间中。

因为name出有做用域,Django正在反解URL时,会正在项目齐局挨次搜刮,当查找到第1个name指定URL时,立刻前往

我们正在开辟项目时,会常常利用name属性反解出URL,当没有谨慎正在差别的app的urls中界说不异的name时,能够会致使URL反解毛病,为了不这类工作产生,引进了定名空间。

创立1个app02:python manage.py startapp app02

总urls.py

from django.urls import path,re_path,include
urlpatterns = [
  path('app01/', include('app01.urls')),
  path('app02/', include('app02.urls'))
]

app01 的urls.py

from django.urls import path,re_path
from app01 import views
urlpatterns = [
  re_path(r'index/',views.index,name='index'),
]

app02 的urls.py

from django.urls import path, re_path, include
from app02 import views

urlpatterns = [
  re_path(r'index/', views.index,name='index'),

]

app01的视图函数

def index(request):
  url=reverse('index')
  print(url)
  return HttpResponse('index app01')

app02的视图函数

def index(request):
  url=reverse('index')
  print(url)
  return HttpResponse('index app02')

如许皆找index,app01战app02找到的皆是app02的index

若何处置?正在路由分收的时分指命名称空间

总urls.py正在路由分收时,指命名称空间

 path('app01/', include(('app01.urls','app01'))),
 path('app02/', include(('app02.urls','app02')))
url(r'app01/',include('app01.urls',namespace='app01')),
 url(r'app02/',include('app02.urls',namespace='app02'))
 url(r'app01/',include(('app01.urls','app01'))),
 url(r'app02/',include(('app02.urls','app02')))

正在视图函数反背剖析的时分,指定是阿谁称号空间下的

 url=reverse('app02:index')
 print(url)
 url2=reverse('app01:index')
 print(url2)

正在模版里:

7 django2.0版的path

django2.0的re_path战1.0的url1样

思虑状况以下:

urlpatterns = [ 
  re_path('articles/(?P[0⑼]{4})/', year_archive), 
  re_path('article/(?P[a-zA-Z0⑼]+)/detail/', detail_view), 
  re_path('articles/(?P[a-zA-Z0⑼]+)/edit/', edit_view), 
  re_path('articles/(?P[a-zA-Z0⑼]+)/delete/', delete_view), 
]

 斟酌下如许的两个成绩:

第1个成绩,函数 year_archive 中year参数是字符串范例的,因而需求先转化为整数范例的变量值,固然year=int(year) 没有会有诸如如TypeError或ValueError的非常。那末有无1种办法,正在url中,使得那1转化步调能够由Django主动完成?

第2个成绩,3个路由中article_id皆是一样的正则表达式,可是您需求写3遍,当以后article_id划定规矩改动后,需求同时修正3处代码,那末有无1种办法,只需修正1处便可?

正在Django2.0中,可使用 path 处理以上的两个成绩。

根本示例

那是1个简朴的例子:

from django.urls import path 
from . import views 
urlpatterns = [ 
  path('articles/2003/', views.special_case_2003), 
  path('articles//', views.year_archive), 
  path('articles///', views.month_archive), 
  path('articles////', views.article_detail), 

  # path才撑持,re_path没有撑持
  path('order/',views.order),
] 

根本划定规矩:

  • 利用尖括号(<>)从url中捕捉值。
  • 捕捉值中能够包括1个转化器范例(converter type),好比利用 捕捉1个整数变量。若果出有转化器,将婚配任何字符串,固然也包罗了 / 字符。
  • 无需增加前导斜杠。

以下是按照 2.0民圆文档 而收拾整顿的示例阐发表:(跟下面url的婚配干系)

 

path转化器

文档本文是Path converters,久且翻译为转化器。

Django默许撑持以下5个转化器:

  • str,婚配除途径分开符(/)以外的非空字符串,那是默许的情势
  • int,婚配正整数,包括0。
  • slug,婚配字母、数字和横杠、下划线构成的字符串。
  • uuid,婚配格局化的uuid,如 075194d3⑹885⑷17e-a8a8⑹c931e272f00。
  • path,婚配任何非空字符串,包括了途径分开符(/)(不克不及用?)

注册自界说转化器

对1些庞大或复用的需求,能够界说本身的转化器。转化器是1个类或接心,它的请求有3面:

  • regex 类属性,字符串范例
  • to_python(self, value) 办法,value是由类属性 regex 所婚配到的字符串,前往详细的Python变量值,以供Django通报到对应的视图函数中。
  • to_url(self, value) 办法,战 to_python 相反,value是1个详细的Python变量值,前往其字符串,凡是用于url反背援用。

例子:

class FourDigitYearConverter: 
  regex = '[0⑼]{4}' 
  def to_python(self, value): 
    return int(value) 
  def to_url(self, value): 
    return '%04d' % value 

利用register_converter 将其注册到URL设置装备摆设中:

from django.urls import register_converter, path 
from . import converters, views 
register_converter(converters.FourDigitYearConverter, 'yyyy') 
urlpatterns = [ 
  path('articles/2003/', views.special_case_2003), 
  path('articles//', views.year_archive), 
  ... 
] 

以上便是本文的全数内容,期望对各人的进修有所帮忙,也期望各人多多撑持剧本之家。