路由分发决定哪一个路由由哪一个视图函数来处理。

注意:django2.0里的re_path和django1.0里的url除了名字不一样,其他都一样。

简单配置

from django.urls import path,re_path

from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/',views.timer), # 路由配置: 决定哪一个路由由哪一个视图函数来处理
# repath和django1.0里的url用法一样
# 不写^,articles前面可以写任何东西(edward/123/articles);同理,不写$,2003后面也可以写任何东西。
re_path(r'^articles/2003/$',views.special_case_2003), # 正则匹配年份
# 如果是2003,会匹配第一个
# 如果去掉$就不走第三个了,因为匹配到年份那就不往后匹配了,而是直接执行arvhive_year了。
re_path(r'^articles/([0-9]{4})/$',views.archive_year), # year_archive(request,1999)。django2.1.5不用传第二个参数了 re_path(r'^articles/([0-9]{4})/([0-9]{2})/$',views.month_archive), # re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

注意:

  • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。

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

  • 每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义

有名分组

# urls
# 有名分组,?P<year>相当于是起了个名字,然后把名字当做参数传给视图函数,后面才是正则部分。
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.month_archive),
'''
month_archive(request,year=2009,momth=12)
这样在views视图,不管传入的参数的顺序是什么,year就是year,month就是month,但是名字必须是year和month
''' #views
def month_archive(request, month,year): # 顺序颠倒也没有问题,不管顺序是什么都会正常显示year和month
return HttpResponse('year:%s,month:%s' % (year,month))

路由分发

在app01下面重新创建一个urls的文件,把关于app01的url放到里面,然后再在公共项目的urls里导入app01的urls

# app01 urls.py
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-9]{4})/$', views.archive_year), # year_archive(request,1999)。
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
] # demo urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer), # 分发:
re_path(r'^app01', include('app01.urls')),
# re_path(r'^', include('app01.urls') # 路径里面不用写app01了
]

反向解析

反向解析就是给url起一个别名,我们用别名去找这个url就行,这样不管url如何改变,我们都可以用别名找到它。

1. 在模板中进行反向解析

urls.py

from django.urls import path, re_path, include

from app01 import views

urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer),
path('login.html/',views.login,name='Log'), # 分发:
re_path(r'^', include('app01.urls')),
]

login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body> <!-- 在render的时候,去urls里找一个name叫Log的url,这样action里永远都是最新的url -->
<form action="{% url 'Log' %}" method="post">
用户名 <input type="text" name="user">
密码 <input type="password" name="pwd">
<input type="submit">
</form> </body>
</html>

2. 在视图函数里进行反向解析

# app01 urls

re_path(r'^articles/2003/$', views.special_case_2003,name ='s_c_2003'),
re_path(r'^articles/([0-9]{4})/$', views.archive_year,name='y_a'), from django.urls import reverse
def special_case_2003(request):
url = reverse('s_c_2003') # 不需要参数,因为不含正则是一个完整的url,找到后直接匹配
url2 = reverse('y_a',args=(4009,)) # ^articles/([0-9]{4})/ 需要给一个四位数字的参数,匹配正则,参数可以是任意四位数字,具体数字按需求写。
print(url) # /articles/2003/
print(url2) # /articles/4009/
return HttpResponse("<h3>special_case_2003</h3>") # HttpResponse里面写的是响应体的内容

命名空间

主项目 urls.py

from django.urls import path, re_path, include

from app01 import views

urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer),
path('login.html/', views.login, name='Log'), # 分发:
# 命名空间不可以重名
re_path(r'^app01', include(('app01.urls', 'app01'))),
re_path(r'^app02', include(('app02.urls', 'app02'))),
]

app01

 # urls
re_path('index/',views.index,name='index') # views
def index(request): # return HttpResponse(reverse('index')) # 找到的也是app02的index,用名称空间解决这个问题。 # 用命名空间解决
return HttpResponse(reverse('app01:index')) # # 冒号之前是namespace,冒号之后是名字

app02

# urls
re_path('index/',views.index,name='index') # views
def index(request): # return HttpResponse(reverse('index')) # 找到的app02的index,用命名空间解决名字冲突的问题 return HttpResponse(reverse('app02:index'))

path方法(django2.0)

re_path有两个问题:

1.不能进行字符转换。

def month_archive(request, month, year):
print(type(month)) # str
print(type(year)) # str
return HttpResponse('year:%s,month:%s' % (year, month))

2.同样的正则表达式,需要写多遍,不易于维护。

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

而path可以解决这两个问题

# urls
from django.urls import path
path('articles/<int:year>',views.path_year) #views
def path_year(request,year):
print(type(year)) # int
return HttpResponse('path year')

基本规则:

  • 使用尖括号(<>)从url中捕获值。

  • 捕获值中可以包含一个转化器类型(converter type),比如使用 <int:name> 捕获一个整数变量。若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。

  • 无需添加前导斜杠。

path转换器

Django默认支持以下5个转化器:

  • str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式

  • int,匹配正整数,包含0。

  • slug,匹配字母、数字以及横杠、下划线组成的字符串。

  • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。

  • path,匹配任何非空字符串,包含了路径分隔符

自定义path转换器

在实际开发中,django自带的转换器是不能满足我们的需求的,这就需要自定义转换器了

操作步骤:

1.在app里创建一个类,写自定义转换的规则

url_convert.py

class MonConvert:
regex = "[0-9]{2}" # 只能叫regex def to_python(self, value):
return int(value) # 不转化就是字符串,可以根据需求做任何操作。 def to_url(self, value): # 用于反向解析
return "%04d" % value

2.在urls里注册自定义转换器

from django.urls import path, re_path, include,register_converter
from app01.url_convert import MonConvert # 注册自定义转换器
register_converter(MonConvert,'mm')

3.在路由分发里使用自定义转换器

urlpatterns = [
path('articles/<mm:month>',views.path_month),
]

Registering custom path converters

For more complex matching requirements, you can define your own path converters.

A converter is a class that includes the following:

  • regex class attribute, as a string.
  • to_python(self, value) method, which handles converting the matched string into the type that should be passed to the view function. It should raise ValueError if it can’t convert the given value.
  • to_url(self, value) method, which handles converting the Python type into a string to be used in the URL.

django之路由分发的更多相关文章

  1. Django之路由分发系统

    web的基本工作流程 首先,我们先来思考一下我们平常在上网浏览网页时候的场景,大致就是打开一个web浏览器,输入某一个网站的地址,然后转到该网址,在浏览器中得到该网址的页面.从这个场景中我们可以抽象出 ...

  2. Django之路由分发和反向解析

    一.路由分发: 路由分发是指:总路由不再直接做路由与视图函数的对应关系,而是将获取的路由分发给下面的app去处理对应关系 from django.conf.urls import url,includ ...

  3. Django之路由分发反向解析

    Django路由分发|反向解析 当一个Django中有多个app时,路由会有很多,将这些路由都写在与项目同名的文件夹下就会显得很多,很乱.并且在协同开发的时候容易出现相同的命名,当项目合并后就会出现路 ...

  4. Django的路由分发与名称空间

    路由分发 django每一个app下面都可以有自己的urls.py路由层,templates文件夹,static文件夹 项目名下urls.py(总路由)不再做路由与视图函数的匹配关系而是做路由的分发 ...

  5. Django框架路由分发-名称空间

    目录 一:路由分发 1.路由分发简介 2.总路由分发配置 3.总路由终极配置(不需要导应用路由,直接点应用即可) 4.子路由配置 二:名称空间 1.名称空间应用场景 3.解决方式二>>&g ...

  6. Django学习之十一:真正理解Django的路由分发和反解url原理

    目录 URL Dispatcher 简介 模式概念 对比URLPattern 与 URLResolver (多态的体现) 构建子路由几种方式 反解url算法逻辑 URL Dispatcher 简介 d ...

  7. $Django 路由层(有,无名分组、反向解析、总路由分发、名称空间、伪静态)

    1 简单配置 -第一个参数是正则表达式(如果要精准匹配:'^publish/$')  -第二个参数是视图函数(不要加括号)  -url(r'^admin/', admin.site.urls), 注: ...

  8. django 路由分发

    对于一个大的工程,可能会有很多应用,比如cmbd,moniter,openstack等等,我们就要用到路由分发 1,首先在跟工程同名的文件夹下的urls中写分发表: from django.conf. ...

  9. Django学习手册 - 正则URL路由配置/路由分发

    ############################################### 总结: 一.url路由配置: 方式一:(通过url链接get获取) 方式二:(url路由匹配方式获取-拓 ...

随机推荐

  1. (四)Redis主从复制(单机版,不集群)

    持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可 ...

  2. 《C#高效编程》读书笔记09-避免在API中使用转换操作符

    转换操作符为类之间引入了一种"可替换性"(substitutability)."可替换性"表示一个类的实例可以替换为另一个类的实例. public class ...

  3. C 碎片十 关键字&库函数

    一.关键字 1, sizeof sizeof关键字用于计算所占空间大小的 格式:sizeof(类型名/变量名); 2, typedef typedef关键字用于重命名数据类型的,相当于给原来的数据类型 ...

  4. Spring Boot 的配置文件application.properties

    Spring Boot 中的application.properties 是一个全局的配置文件,放在src/main/resources 目录下或者类路径的/config下. 作为全局配置文件的app ...

  5. AD7190的小总结

    1.单次转换模式 通过配置“模式寄存器的MD2.MD1.MD0为001”,便可启动单次转换. 流程“上电 -> 单次转换 -> 省电模式 ” , 片内振荡上电需要大约1ms.   单次转换 ...

  6. HDU1043 八数码(BFS + 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...

  7. Java中的字符串问题

    本文章分为三个部分: 1.创建字符串对象的两种方式以及它们的存储方式 2.String a = new String("a")创建了几个对象的问题 3.字符串小例子 ------- ...

  8. Google Guava入门(一)

    Guava作为Java编程的助手,可以提升开发效率,对Guava设计思想的学习则极大的有益于今后的编程之路.故在此对<Getting Started with Google Guava>一 ...

  9. 工作流性能优化(敢问activiti有扩展性?)(2)

    2015/4/17 粗略看了activiti的sql的,在ativity engine包里边: 没什么头绪,先用excel记录数据量少的时候本机的性能情况:   不打印hibernate的sql:一刷 ...

  10. sparkSQL中udf的使用

    在Spark中使用sql时一些功能需要自定义方法实现,这时候就可以使用UDF功能来实现 多参数支持 UDF不支持参数*的方式输入多个参数,例如String*,不过可以使用array来解决这个问题. 定 ...