第十章 Django的路由

10.1. URLConf

  • URL配置(URLconf)就像是Django所支撑网站的目录。

  • 它的本质是URL与要为该URL调用的视图函数之间的映射表。

  • 我们就是以这种方式告诉Django,遇到哪个URL的时候,要对应执行哪个函数。

10.1.2 Django处理请求

  1. Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF setting, but if the incoming HttpRequest object has a urlconf attribute (set by middleware), its value will be used in place of the ROOT_URLCONF setting。

  2. Django loads that Python module and looks for the variable urlpatterns. This should be a Python list of django.conf.urls.url() instances. # 返回一个对象

  3. Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.

  4. Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function (or a class-based view). The view gets passed the following arguments:

    • An instance of HttpRequest.

    • If the matched regular expression returned no named groups, then the matches from the regular expression are provided as positional arguments.

    • The keyword arguments are made up of any named groups matched by the regular expression, overridden by any arguments specified in the optional kwargs argument to django.conf.urls.url().

  5. If no regex matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view. See Error handling below.

10.2. 基本格式

from django.conf.urls import url
urlpatterns = [
     url(正则表达式, views视图,参数,别名),
]
  • 示例
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),
]

10.2.1 Django 1.11参数

  1. 正则表达式:一个正则表达式字符串

  2. views视图:一个可调用对象,通常为一个视图函数

  3. 参数:可选的要传递给视图函数的默认参数(字典形式)

  4. 别名:一个可选的name参数

10.2.2 Django 2.0

from django.urls import path,re_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),
]
  • 2.0版本中re_path和1.11版本的url是一样的用法。

10.3. 正则表达式

10.3.1 注意事项(4)

  1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续

  2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号分组匹配)。

  3. 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。

  4. 每个正则表达式前面的'r' 是可选的但是建议加上。

  • APPEND_SLASH = True(默认为True),如果没有 / Django会发送重定向,location:/xxx/ 会加上 /。当设置为False时,如果访问路径不包含 / ,则会找不到页面

10.3.2 分组

  • 位置传参

  • urls.py中的正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式传递给视图

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

urlpatterns = [
    url(r'^bolg/([0-9]{4})/(\d{2})', views.blog),
]
# URL: /bolg/2008/08
def blog(request, year, month):
      return HttpResponse('ok')
# 调用方式
blog(request, '2008', '08')

10.3.3 分组命名匹配

  • 关键字传参

  • 捕获的的参数都是string类型

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

urlpatterns = [
    url(r'^bolg/(?P<year>[0-9]{4})/(?P<month>\d{2})', views.blog),
]
# URL: /bolg/2008/08
def blog(request, year, month):
      return HttpResponse('ok')
# 调用方式
blog(request, year='2008', month='08')

Note(4)

  1. URLconf 不检查请求的方法。

  2. 换句话讲,所有的请求方法,同一个URL的POST、GET、HEAD等等,都将路由到相同的函数。

  3. 每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。

  4. 可以为关键字传参的view函数,指定默认值,应用于分页

10.4. include()方法

参数

  • urls.py 的导入,如'app.urls'

  • namespace='app'

10.4.1 基本使用

  • 主要作用是进行路由的二级分发

  • 导入include,from django.conf.urls import include

# At any point, your urlpatterns can “include” other URLconf modules. This essentially “roots” a set of URLs below other ones.

# For example, here’s an excerpt of the URLconf for the Django website itself. It includes a number of other URLconfs
from django.conf.urls import include, url
urlpatterns = [
       url(r'^admin/', admin.site.urls),
      # 可以包含其他的URLconfs文件,路由分发
      url(r'^blog/', include('blog.urls')),   
]

10.4.2 传递额外参数

  • 如果命名分组名和传参名相同则优先选择,关键字传参的值

  • 源码采用传参的dict数据更新命名分组的dict数据。

# app(bolg)内的urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
    # 传递关键字参数给视图,类型为字典中的type。优先级比命名分组优先级要高
      url(r'^blog/', views.blog, {'year': 2008}),   
]
  • settings.py中的ROOT_URLCONFG='xxx.urls',表示核心路由起始位置,可根据需求进行更改

10.4.3 命名url和url反向解析

  • 在使用Django 项目时,一个常见的需求是获得URL的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。

  • 命名url和url反向解析,就是一个DRY(Don't repeat yourself) 机制。

  • 解决硬编码不灵活的问题。

1. 命名url

  • 给url地址命名

url(r'^blog/', views.blog, {'year': 2008}, name='blog'),

反向解析又称为反向解析URL、反向URL 匹配、反向URL 查询或者简单的URL 反查。

  1. 通过命名生成url路径的完整路径

  2. 应用在:模版和py文件中

2. 静态路由

{# 获取的是完整的url路径,string类型 #}
{% url 'blog' %}
  • 获取完整到 url 路径,通过name进行反向解析,即通过urls.py获取
# views.py
# 也可以通过django.shortcuts 导入
from django.urls import reverse
url = reverse('blog')

3. 分组

  • urls.py文件中配置

url(r'^bolg/([0-9]{4})/(\d{2})', views.blog, name='blog'),
  • py文件中使用
# py文件, args为tuple 推荐最后一个参数加 , 
url = reverse('blog', args=('2008', '08',))
  • 模版中使用
{# 使用 #}
{% url 'blog' 2011 12 %}

4. 命名分组

  • urls.py文件中配置

  • 使用时,可以按照位置传参

url(r'^bolg/(?P<year>[0-9]{4})/(?P<month>\d{2})', views.blog, name='blog')
  • py文件中使用
# 在py文件中使用, args为tuple 推荐最后一个参数加 , 
url = reverse('blog', args=('2008', '08',))
url = reverse('blog', kwargs={'year': '2008', 'month': '08'})
  • 模版中使用
{# 在模版中使用 #}
{% url 'blog' 2011 12 %}
{% url 'blog' year=2011 month=12 %}

5. namespace

  • 命名空间,解决多个app中的name相同的情况,后面的name会覆盖之前的name,造成url解析错误的问题

url(r'^app01/', include('app01.urls'), namespace='app01')
url(r'^app02/', include('app02.urls'), namespace='app02')
  • 反向解析时,需要在name前添加 namespace的值

  • name通常加在 app下的urls.py文件中的url

  • namespace可以进行多级嵌套 使用冒号 : 进行使用

{% url 'namespace值:blog' %}
{% url 'app01:blog' %}
{% url 'app02:blog' %}
url = reverse('app01:blog')

 

 

 

posted @ 2020-05-20 12:14  炜琴清  阅读(241)  评论(0编辑  收藏  举报