1、工作原理

django通过urlconf来映射视图函数,只区分路径,不区分http方法

  • Django确定要使用的根URLconf模块,一般是在settings中的ROOT_URLCONF设置的值。
  • Django加载该URLconf模块并查找变量 urlpatterns,它是一个列表django.urls.path() 和 / 或django.urls.re_path()实例。根据列表的实例查找相关的路劲。
  • Django按顺序遍历每个URL模式,并停在与请求的URL匹配的第一个URL模式,后面相同的模式不会再进行匹配。
  • 如果某个URL模式匹配成功,Django就会导入并调用给定的视图,该视图是一个简单的Python函数(或基于类的视图方法)。

2、简单示例:

from django.urls import path

from . import views

urlpatterns = [
path('blog/2003/', views.special_2003),
path('blog/<int:year>/', views.year_archive),
path('blog/<int:year>/<int:month>/', views.month_archive),
path('blog/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]

在上述路由中,有几点需要注意:

(1)从URL中捕获,使用尖括号。

(2)捕获的值可以包含转换器,如/<int:year>/,前面的int表示只能是整数参数,year是参数的名称,用于视图函数的参数传递

(3)path的路径前不需要再添加“/”,

(4)示例说明

blog/2003/匹配的是path('blog/2003/', views.special_2003),而blog/2005/匹配的是path('blog/<int:year>/', views.year_archive),

3、格式转换器

在上面的示例中,我们已经看到了int这个格式转换器的用法,格式转换器还有:

str:匹配任何非空字符串,不包括路径分隔符'/'。表达式中不包含转换器,则默认为str。

int:匹配零或任何正整数。返回一个int。

slug:匹配由ASCII字母或数字组成的字符串,以及横线和下划线字符。例如, building-your-1st-django_url。

uuid:匹配格式化的UUID。为防止多个URL映射到同一页面,必须包含破折号,并且字母必须是小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID实例。

path:匹配任何非空字符串,包括路径分隔符 '/',可以匹配完整的URL路径,而不仅仅是URL路径的一部分str,使用时要谨慎,因为可能造成后续的所有url匹配都失效。

------------恢复内容开始------------

1、工作原理

django通过urlconf来映射视图函数,只区分路径,不区分http方法

  • Django确定要使用的根URLconf模块,一般是在settings中的ROOT_URLCONF设置的值。
  • Django加载该URLconf模块并查找变量 urlpatterns,它是一个列表django.urls.path() 和 / 或django.urls.re_path()实例。根据列表的实例查找相关的路劲。
  • Django按顺序遍历每个URL模式,并停在与请求的URL匹配的第一个URL模式,后面相同的模式不会再进行匹配。
  • 如果某个URL模式匹配成功,Django就会导入并调用给定的视图,该视图是一个简单的Python函数(或基于类的视图方法)。

2、简单示例:

from django.urls import path

from . import views

urlpatterns = [
path('blog/2003/', views.special_2003),
path('blog/<int:year>/', views.year_archive),
path('blog/<int:year>/<int:month>/', views.month_archive),
path('blog/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]

在上述路由中,有几点需要注意:

(1)从URL中捕获,使用尖括号。

(2)捕获的值可以包含转换器,如/<int:year>/,前面的int表示只能是整数参数,year是参数的名称,用于视图函数的参数传递

(3)path的路径前不需要再添加“/”,

(4)示例说明

blog/2003/匹配的是path('blog/2003/', views.special_2003),而blog/2005/匹配的是path('blog/<int:year>/', views.year_archive),

3、格式转换器

在上面的示例中,我们已经看到了int这个格式转换器的用法,格式转换器还有:

str:匹配任何非空字符串,不包括路径分隔符'/'。表达式中不包含转换器,则默认为str。

int:匹配零或任何正整数。返回一个int。

slug:匹配由ASCII字母或数字组成的字符串,以及横线和下划线字符。例如, building-your-1st-django_url。

uuid:匹配格式化的UUID。为防止多个URL映射到同一页面,必须包含破折号,并且字母必须是小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID实例。

path:匹配任何非空字符串,包括路径分隔符 '/',可以匹配完整的URL路径,而不仅仅是URL路径的一部分str,使用时要谨慎,因为可能造成后续的所有url匹配都失效。

4、自定义格式转换器

转换器包含以下类:

一个regex类属性,作为一个re匹配字符串。

to_python(self, value)方法,它处理匹配的字符串转换成要传递到视图函数的类型。

o_url(self, value)方法,用于处理将Python类型转换为URL中使用的字符串。

转换器的定义方式如下:

(1)新建一个converters.py文件,在文件中定义一个类,使用to_python()和to_url()方法处理

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

(2)使用register_converter()方法在URLconf中注册自定义转换器类 :

在需要注册的url.py文件中注册,先从django.urls中导入register_converter,同时导入自定义的类注册

   from django.urls import register_converter, path

   from . import converters, views

  # 注册自定义的转换器
register_converter(converters.YearConverter, 'yyyy') urlpatterns = [
path('blog/2003/', views.special_2003),
path('blog/<yyyy:year>/', views.year_archive)
]

5、正则表达式的使用

使用正则表达式匹配路径时,使用re_path()。

在python正则表达式中,命名正则表达式的语法是(?P\<year>pattern),year是组的名称,pattern是需要匹配的模式。

from django.urls import path, re_path

from . import views

# url() 是 re_path 的别名,不推荐使用
urlpatterns = [
path('blog/2003/', views.special_2003),
path('blog/<int:year>/', views.year_archive),
re_path(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive),
re_path(r'^blog/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',
views.month_archive),
re_path(r'^blog/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]

在上述正则表达式中:

^表示匹配开头,$表示匹配结束。

[0-9]{4}表示匹配4位0到9的数。

6、错误处理

- handler400- 状态码400
- handler403- 状态码403
- handler404- 状态码404
- handler500- 状态码500

(1)setting中修改设置

   DEBUG = False

   ALLOWED_HOSTS = ['*', ]

(2)在主应用urls中配置

# blog表示子应用名
handler404 = "blog.views.page_not_found"

(3)在视图函数中定义以下函数

   def page_not_found(request, exception):
return HttpResponse('这是一个自定义的404错误页面')

我们看一下页面显示结果:当url找不到时,便会展示我们定义的404错误信息。

7、应用其他url调度器

在同一个url中,为了避免重复的路由输入,可以采用多个patterns的方法,示例如下:

   from django.urls import include, path

    """原生代码:
urlpatterns = [
path('blog/reports/', credit_views.report),
path('blog/reports/<int:id>/', credit_views.report),
path('blog/charge/', credit_views.charge),
]
"""
# 修改后的代码
blog_patterns = [
path('reports/', credit_views.report),
path('reports/<int:id>/', credit_views.report),
path('charge/', credit_views.charge),
] urlpatterns = [
path('blog/', include(blog_patterns)),
]

采用include()的方法

   from django.urls import path
from . import views urlpatterns = [
path('<page_slug>-<page_id>/history/', views.history),
path('<page_slug>-<page_id>/edit/', views.edit),
path('<page_slug>-<page_id>/discuss/', views.discuss),
path('<page_slug>-<page_id>/permissions/', views.permissions),
] # 修改为:
from django.urls import include, path
from . import views urlpatterns = [
path('<page_slug>-<page_id>/', include([
path('history/', views.history),
path('edit/', views.edit),
path('discuss/', views.discuss),
path('permissions/', views.permissions),
])),
]

7、URL反向解析

(1)url调度器除了从用户发起请求,到匹配对应的view,还能在python程序中调用进行匹配,通过 path或re_path 中 的name属性进行解析。

在模板中,使用url模板标签,在url中,使用了name属性

from django.urls import path
from . import views urlpatterns = [
#...
path('blog/<int:id>/', views.id_archive, name='id-archive'),
#...
]

在HTML模板中,我们可以使用url标签进行解析,方法示例如下:

<a href="{% url 'id-archive' 20 %}">20 Archive</a>
<ul>
{% for idvar in id_list %}
<li><a href="{% url 'id-archive' idvar %}">{{ idvar }} Archive</a></li>
{% endfor %}
</ul>
href="{% url 'id-archive' 20 %}中"id-archive"就是name的属性。
(2)在Python代码中(主要是views视图中),使用 reverse() 函数。
from django.urls import reverse
from django.http import HttpResponseRedirect def redirect_to_id(request):
# ...
num = 20
# ...
return HttpResponseRedirect(reverse('news-year-archive', args=(num,)))

使用reverse进行重定向,完成url的一个跳转链接。

(3)在模型实例中,使用 get_absolute_url() 方法.

在模型中的实现方法如下:

def get_absolute_url(self):
from django.urls import reverse
return reverse('new-id-archive', args=[str(self.id)])

在模板中的实现方法如下:

<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>

在上述实现方法中,"new-id-archive"是name属性的值,args是传入的参数值

8、命名空间

主要用于配合url反向解析使用,多个不同的urls文件中可能配置同名的name,那么为了进行区分,给不同的urls进行不同的命名,同一个项目下命名空间一定不能重复。

在url调度器的模块中,使用app_name = "名字"来命名。

from django.urls import path

from . import views
# 定义,一般命名空间和子应用名相同,便于记忆
app_name = 'blog'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
...
]

当使用了命名空间之后,调用时必须有命名空间的前缀,其方法如下所示:

def test_app_name(request):
return HttpResponseRedirect(reverse('blog:index'))
'blog:index',blog表示命名空间的名字,index表示name属性的值

命名空间的嵌套使用,嵌套与patterns中,如下所示:
from django.urls import path

from . import views
# 定义命名空间,一般命名空间名和子应用名相同,便于记忆
app_name = 'blog' blog_patterns = (
[
path('app_name/', views.app_name, name='app_name'),
],
# 此处就是嵌套的命名空间
'reading'
) urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('reading/', include(blog_patterns)),
...
]

在模板中使用嵌套空间的方法

<a href="{% url 'blog:reading:app_name' %}">点击链接</a>

<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>

02-URLConf调度器的更多相关文章

  1. Django 源码小剖: URL 调度器(URL dispatcher)

    在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 URL. 这是 django url 匹配处理机制的 ...

  2. CDN调度器HAProxy、Nginx、Varnish

    http://www.ttlsa.com/web/the-cdn-scheduler-nginx-haproxy-varnish/ CDN功能如下:1.将全网IP分为若干个IP段组,分组的依据通常是运 ...

  3. Spring 3 调度器示例 —— JDK 定时器和 Quartz 展示

    Spring框架提供了执行和调度任务的抽象,支持线程池或者在应用服务器环境中代理给CommonJ. Spring也集成了支持使用JDK Timer和Quartz调度库提供的Quartz Schedul ...

  4. URL 调度器(URL dispatcher)

    URL 调度器(URL dispatcher) 在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 UR ...

  5. MySQL事件调度器event的使用

    Q:假设,有一个需求,希望在某一个时刻系统调用一个begin end执行一下:十分钟以后执行一下begin end.亦或有一个需求,每个多长时间周期性执行begin end.那么这个时候该怎么办呢? ...

  6. quartz2.3.0(七)调度器中断任务执行,手动处理任务中断事件

    job任务类 package org.quartz.examples.example7; import java.util.Date; import org.slf4j.Logger; import ...

  7. Golang调度器GMP原理与调度全分析(转 侵 删)

    该文章主要详细具体的介绍Goroutine调度器过程及原理,包括如下几个章节. 第一章 Golang调度器的由来 第二章 Goroutine调度器的GMP模型及设计思想 第三章 Goroutine调度 ...

  8. TVM自动调度器

    TVM自动调度器 随着模型大小,算子多样性和硬件异构性的不断增长,优化深度神经网络的执行速度非常困难.从计算的角度来看,深度神经网络只是张量计算的一层又一层.这些张量计算(例如matmul和conv2 ...

  9. 大数据之Yarn——Capacity调度器概念以及配置

    试想一下,你现在所在的公司有一个hadoop的集群.但是A项目组经常做一些定时的BI报表,B项目组则经常使用一些软件做一些临时需求.那么他们肯定会遇到同时提交任务的场景,这个时候到底如何分配资源满足这 ...

随机推荐

  1. (十一)Maven之profile实现多环境配置动态切换

    原文链接:https://www.cnblogs.com/zeng1994/p/a442108012ffd6a97b22c63055b48fe9.html 一.多环境配置文件的放置  将不同环境下的配 ...

  2. python反向遍历一个可迭代对象

    我们通常情况下都是正向遍历一个列表,下面是一种简单的反向遍历一个列表的方式. ## 正向遍历 >>>A = [9, 8, 7] >>>for index, a in ...

  3. 多线程高并发编程(11) -- 非阻塞队列ConcurrentLinkedQueue源码分析

    一.背景 要实现对队列的安全访问,有两种方式:阻塞算法和非阻塞算法.阻塞算法的实现是使用一把锁(出队和入队同一把锁ArrayBlockingQueue)和两把锁(出队和入队各一把锁LinkedBloc ...

  4. 解决mysql插入数据l出现"the table is full"的问题

    需要修改Mysql的配置文件my.ini,在[mysqld]下添加/修改两行:tmp_table_size = 256Mmax_heap_table_size = 256M

  5. CODING DevOps 系列第四课:DevOps 中的质量内建实践

    什么是质量内建 随着时间的推移,我们项目的开发效率会逐渐降低,直到几年之后整个项目可能就无法维护,只能推倒重来.具体的表现首先就是随着时间推移,我们会发现整个需求列表里面能做的需求越来越少,因为每当我 ...

  6. Consul入门初识

    Consul Consul是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,由HashiCrop公司用Go语言开发,基于Mozilla Public License 2.0的协议进行开源 ...

  7. java并发编程-线程生命周期

    线程生命周期 现代操作系统在运行一个程序时,会为其创建一个进程.例如,启动一个Java程序,操作系统就会创建一个Java进程.现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight ...

  8. 009.OpenShift管理及监控

    一 资源限制 1.1 pod资源限制 pod可以包括资源请求和资源限制: 资源请求 用于调度,并控制pod不能在计算资源少于指定数量的情况下运行.调度程序试图找到一个具有足够计算资源的节点来满足pod ...

  9. yum 安装Mysql8.0

    系统: CentOS 7(在CentOS 7中默认有安装MariaDB,这个是mysql的分支,一般来说还是使用自己安装的MySQL比较好) 1.下载并安装MySQL wget -i -c https ...

  10. android 中IntentService的使用场景

    IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行 ...