Django学习笔记之路由系统
Django的路由系统
路由系统的本质就是URL要与这个URL要调用的视图函数之间的映射表。
主要就是在urls.py这个文件中进行配置。具体内容如下:
rom django.conf.urls import url urlpatterns = [ url(路径, views视图函数,参数,别名), ]
路径:要访问的路径,可以使用正则表达式来模糊匹配
views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
- 参数:可选的要传递给视图函数的默认参数(字典形式)
-
别名:一个可选的name参数
-
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
上面的内容是Django1.11版本的内容,在Django2.0之后,发生了一些变化:
from django.urls import path urlpatterns = [ path('articles/2003/', views.special_case_2003), path('articles/<int:year>/', views.year_archive), path('articles/<int:year>/<int:month>/', views.month_archive), path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail), ]
Django2.0之后如果要在路径里面使用这则表达式的话,需要如下内容:
from django.urls import path, re_path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail), ]
需要注意的几个点:
1、urlpatterns 里面写的路径匹配,是按照从上到下的顺序来的,如果第一个匹配满足要求的话,就直接调用对应的视图函数了;
2、在用分组匹配的时候,可以通过分组的组名来捕获到其中的内容;
3、在Django项目中的settings.py配置文件里面,可以加上 APPEND_SLASH=True(Django默认是True),意思是在访问路径的时候自动在后面加上 “ / ”,比如说我们定义了上面的url后,访问http://www.example.com/articles/2003,默认将网址自动转换为 http://www.example/articles/2003/ 。
分组命名匹配
分组命名匹配的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。
按照上面的匹配方式,如果url为 /articles/2017/12/,那么调用视图函数:
views.month_archive(request, year="2017", month="12")
需要注意的是,这个参数year,传递的永远是个字符串类型。
如果没有给year这个参数传值的话,我们还可以在视图函数中指定默认值:
def month_archive(request,year="1"): pass
不同应用处理对应的访问路径
如果一个Django项目里面有多个不同的应用,要实现不同的应用处理其对应的路径时,可以使用include来处理。
from django.conf.urls import url, include from django.contrib import admin from app01 import urls as app01_url from app02 import urls as app02_url urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/', include(app01_url)), url(r'^app02/', include(app02_url)), ]
需要在对应的应用下面新建一个urls.py文件,里面是处理项目的路由传过来的路径,比如说在app01应用下新建urls.py文件,内容是:
from django.conf.urls import url from . import views urlpatterns = [ url(r'home/', views.home), ]
传递额外的参数给视图函数
在路径映射的时候,可以传递一个额外的参数给视图函数:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
命名URL和URL的反向解析
说白了,其实就是给url起一个名字,比如:
url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home url(r'^index/(\d*)', views.index, name='index'), # 给我的url匹配模式起名为index
那么在模板中就可以这样使用:
{% url 'home' %}
在视图函数中可以这样使用:
from django.urls import reverse reverse("index", args=("2018", ))
需要注意的是,name的值不能一样,如果在多个应用中存在相同的name,那么在反向解析的时候就不会指定到你需要的URL,如果一定要一样的话,就需要用 命名空间 来区分。
命名空间
处理不同的APP使用相同的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')), ]
app01中的urls.py如下:
from django.conf.urls import url from app01 import views app_name = 'app01' urlpatterns = [ url(r'^(?P<pk>\d+)/$', views.detail, name='detail') ]
app02中的urls.py如下:
from django.conf.urls import url from app02 import views app_name = 'app02' urlpatterns = [ url(r'^(?P<pk>\d+)/$', views.detail, name='detail') ]
那么在模板中使用命名空间:
{% url 'app01:detail' pk=12 pp=99 %}
在视图函数中使用命名空间:
reverse('app01:detail', kwargs={'pk':11})
这样的话,如果不同应用中存在相同的name,那也可以反向解析成正确的URL了。

浙公网安备 33010602011771号