urls配置像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。

1.简单的urls配置

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.year_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

注意:

  • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
  • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles
  • 每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义

示例:

'''
一些请求的例子: /articles/2005/03/ 请求将匹配列表中的第三个模式。Django 将调用函数views.month_archive(request, '2005', '03')。
/articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。请像这样自由插入一些特殊的情况来探测匹配的次序。
/articles/2003 不匹配任何一个模式,因为每个模式要求URL 以一个反斜线结尾。
/articles/2003/03/03/ 将匹配最后一个模式。Django 将调用函数views.article_detail(request, '2003', '03', '03')。 '''

2.有名分组

  上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中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<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<day>[0-9]{2})/$', views.article_detail),
]

这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:

    '''
/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')。 '''

分发功能:

适用场景:按照我们上面的urls的写法,如果我们有10个应用,每个应用有200条路由,那么我们就要在urls里写上2000条.其实我们应该把相对应的路由写到对应的应用中(在应用中新建一个urls.py,其他名称也可以),这就用到了分发功能

项目下的urls配置:

from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer), # 分发功能:下面的意思:只要是在浏览器中以app01开头的请求,都转到app01.urls路由里去分发
re_path(r"^app01/",include("app01.urls")) ]

应用中urls配置:

from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
# path('admin/', admin.site.urls),
# path('timer/', views.timer), # 路由配置: 路径------>视图函数,哪个路径由哪一个视图函数处理 re_path(r"^articles/2003/$",views.special_2003),#如果路径匹配成功了,相当于调用views.special_2003(request)
re_path(r"^articles/([0-9]{4})/$",views.year),
re_path(r"^articles/([0-9]{4})/([0-9]{2})/$",views.month), # 有名分组:可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。
re_path(r"^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$",views.month), # 传递参数时就会按照关键字参数来传递:views.month(request,year=2009,month=02),同样的,在view视图函数中,month函数也应该接收2个关键字参数
]

反向解析

  在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。

在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:

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

urls.py

from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer),
#反向解析流程:当用户在浏览器上请求login地址时,转到views.login中,在render()的时候,要解析login.html页面,当在页面中发现
#模版语法{% url "LOG"}的时候,会到urls中找别名为LOG的那一条记录,然后取出相应的地址,渲染到login.html中,替换模板语法. # 此时,login/可以更改为任何你想要更改的内容
path('login/', views.login,name="LOG"),
]

模版文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录验证</title>
</head>
<body>
<form action="{% url 'LOG' %}" method="post">
用户名 <input type="text" name="user">
密码 <input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>

视图函数中:

from django.shortcuts import render,HttpResponse
from django.urls import reverse
# Create your views here.
def timer(request):
import time
ctime = time.strftime("%Y-%m-%d %X",time.localtime())
return render(request,"timer.html",{"date":ctime}) def special_2003(request): return HttpResponse("") def year(request,y): return HttpResponse(y) def month(request,year,month): return HttpResponse(year+"-"+month) def login(request):
# 校验用户名密码,得从post请求中,获取到用户输入的user和pwd,所有的请求信息都在request中
#1.获取请求方式是GET还是POST
print(reverse("LOG"))
print(request.method)
if request.method=="GET":
# render的时候,会渲染login.html,当遇到模板语法{}的时候,会到urls中找相应的别名,然后取出路径,渲染到login.html中.再返回给浏览器
return render(request, "login.html")
else:
# 2.post请求信息在request.POST中,这是一个字典形式的数据
print(request.POST)
user = request.POST.get("user")
pwd = request.POST.get("pwd")
if user =="nick" and pwd=="":
return HttpResponse("登录成功!")
else:
return HttpResponse("登录失败,请检查用户名密码!")

注意:如果urls路径中有正则表达式,则需要把相应的规则转换成一个参数传递,否则会报错:Reverse for 'yd' with no arguments not found. 1 pattern(s) tried: ['app01/articles/([0-9]{4})/$']

路径带正则的view函数:

# *_*coding:utf-8 *_*
from django.shortcuts import render,HttpResponse
from django.urls import reverse
# Create your views here.
def timer(request):
import time
ctime = time.strftime("%Y-%m-%d %X",time.localtime())
return render(request,"timer.html",{"date":ctime}) def special_2003(request): return HttpResponse("") def year(request,y):
#这里必须传递一个参数
url = reverse("yd",args=(2000,))
print(url)
return HttpResponse(url) def month(request,year,month): return HttpResponse(year+"-"+month)

带正则匹配的urls:

from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
# path('admin/', admin.site.urls),
# path('timer/', views.timer), # 路由配置: 路径------>视图函数,哪个路径由哪一个视图函数处理 re_path(r"^articles/2003/$",views.special_2003,name="sc2003"),#如果路径匹配成功了,相当于调用views.special_2003(request)
re_path(r"^articles/([0-9]{4})/$",views.year,name="yd"),
re_path(r"^articles/([0-9]{4})/([0-9]{2})/$",views.month), ]

名称空间:

命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其它命名空间中。

由于name没有作用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回
我们在开发项目时,会经常使用name属性反解出URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间.
project中urls:
urlpatterns = [
re_path(r'^admin/', admin.site.urls),
#include的时候,传递一个元组参数,第一个是匹配的路由,第二个是名称空间(可以随意命名)
re_path(r'^app01/', include(("app01.urls",app01"))),
re_path(r'^app02/', include(("app02.urls","app02"))),
]

app01中的urls:

urlpatterns = [
re_path(r'^index/', index,name="index"),
]

app02中的urls:

urlpatterns = [
re_path(r'^index/', index,name="index"),
]

app01.views.py:

from django.core.urlresolvers import reverse

def index(request):

    return  HttpResponse(reverse("app01:index"))

app02.views.py:

from django.core.urlresolvers import reverse

def index(request):
#
return HttpResponse(reverse("app02:index"))

Django2.0 path

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),
]

  考虑下这样的两个问题:

  第一个问题,函数 year_archive 中year参数是字符串类型的,因此需要先转化为整数类型的变量值,当然year=int(year) 不会有诸如如TypeError或者ValueError的异常。那么有没有一种方法,在url中,使得这一转化步骤可以由Django自动完成?

  第二个问题,三个路由中article_id都是同样的正则表达式,但是你需要写三遍,当之后article_id规则改变后,需要同时修改三处代码,那么有没有一种方法,只需修改一处即可?

  在Django2.0中,可以使用 path 解决以上的两个问题。

示例:

from django.urls import path
from . import views
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>/', views.article_detail),
]

基本规则:

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

path转换器:

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

  • str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
  • int,匹配正整数,包含0。
  • slug,匹配字母、数字以及横杠、下划线组成的字符串。
  • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
  • path,匹配任何非空字符串,包含了路径分隔符

自定义转换器:新建一个py文件

# -*- coding: utf-8 -*-

class MonPath(object):

    #定义规则:定义一个2位数
regex ="[0-9]{2}" def to_python(self,value):
return int(value) def to_url(self,value):#用于反向解析
return "%04d" % value

pro urls.py:

from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
from django.urls import register_converter
from app01.urlconvert import * #urlconvert是我们新建的py文件 register_converter(MonPath,"mm") #mm是起的别名.可以随便取
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer), #使用自定义转换器之前,需要早django.urls中导入register_converter,导入我们自定义的转换器,然后使用register_converter,来注册自定义转换器 path("articles/<mm:month>",views.path_month) ]

Django3 Django 路由分发,反向解析,2.0版本的path的更多相关文章

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

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

  2. django路由的反向解析

    什么是路由的反向解析 我们的路由都是一个匹配关系,对应一个处理的视图函数, 如果我们的匹配关系发生了变化,那么与之对应的访问地址(可能前端直接url链接, 也可能是后端的redrict跳转)都需要跟着 ...

  3. Django 的路由层URL 分组 路由分发 反向解析

    URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调 ...

  4. stark组件前戏(3)之django路由分发的本质include

    django路由分发的三种方式 方式一: from django.urls import re_path, include urlpatterns = [ re_path(r'^web/', incl ...

  5. django之路由分组,反向解析,有名,无名分组

    路由层 无名分组 有名分组 反向解析 路由分发 名称空间 伪静态的概念 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'test',vi ...

  6. day53:django:URL别名/反向解析&URL分发&命名空间&ORM多表操作修改/查询

    目录 1.URL别名&反向解析 2.URL分发&命名空间 3.ORM多表操作-修改 4.ORM多表操作-查询 4.1 基于对象的跨表查询 4.2 基于双下划线的跨表查询 4.3 聚合查 ...

  7. drf路由分发、解析/渲染模块配置、使用admin、自动序列化配置

    目录 drf路由分发配置 解析模块配置 渲染模块配置 浏览器渲染打开 浏览器渲染关闭 结论 drf使用后台admin drf序列化模块 serializers.py: views.py:单查群查 测试 ...

  8. Django之url反向解析

    在urls.py文件中,在进行url映射时,为请求的url命个名,以便在模板页面或者views.py视图中可以进行反向解析,同时在修改了url映射的请求路径,名称不变的情况下,不再修改模板页面或者视图 ...

  9. django url配置-反向解析-视图函数-HttpRequest对象-HttpResponse对象-cookies-session-redis缓存session

    """ --视图概述:-- 作用:视图接受WEB请求,并响应WEB请求 本质:视图就是一个python中的函数 响应: 1.网页: 一.重定向 二.错误视图 400,50 ...

随机推荐

  1. 我的2018OKR年终回顾与2019OKR初步规划

    转眼一年又过去了,在这个年底的时候,按照国际惯例,又到了重新回顾审视一下这一年来的得失,规划一下明年的奋斗方向的时候了.因此,我继续使用OKR来给自己做Review和Planning,也希望自己能够保 ...

  2. 机器学习——决策树,DecisionTreeClassifier参数详解,决策树可视化查看树结构

    0.决策树 决策树是一种树型结构,其中每个内部节结点表示在一个属性上的测试,每一个分支代表一个测试输出,每个叶结点代表一种类别. 决策树学习是以实例为基础的归纳学习 决策树学习采用的是自顶向下的递归方 ...

  3. Redis缓存你必须了解的!

    不管你是从事Python.Java.Go.PHP.Ruby等等… Redis都应该是一个比较熟悉的中间件.而大部分经常写业务代码的程序员,实际工作中或许只用到了set value.get value两 ...

  4. GitHub 可以免费创建私人仓库啦

    如果你不知道什么是 GitHub,也可以往下看,只不过可能感受不会那么深啦. 昨天,GitHub 博客发表了文章 其中比较重要的已经用蓝色线标注了. GitHub 支持开发者创建免费私人仓库,但是需要 ...

  5. jQuery里面的DOM操作(查找,创建,添加,删除节点)

    一:创建元素节点(添加) 创建元素节点并且把节点作为元素的子节点添加到DOM树上 append(): 在元素下添加元素 用法:$("id").append("定义的节点& ...

  6. Java基础差,需要怎么补

    本文首发于本博客 猫叔的博客,转载请申明出处 感谢sugar的提问:Java基础差,需要怎么补? 欢迎关注公众号:Java猫说 我整体的总结了一下,大致分为以下的几个点说一下: 1.善于使用搜索引擎 ...

  7. WebGL或OpenGL关于模型视图投影变换的设置技巧

    目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在 ...

  8. 二、Snapman多人协作电子表格之——软件下载安装与配置

    Snapman多人协作电子表格是一个即时工作系统. 一.软件下载地址 Snapman下载的官网地址:http://www.snapman.xyz 在官网下载Snapman主程序安装: snapman_ ...

  9. Ajax - Apache安装配置

    apache安装配置 1.安装wamp2.配置根路径3.默认的网站根路径是安装目录的www子目录,如果不想使用默认目录,可以自己配置.配置方式如下: --找到文件wamp\bin\apache\Apa ...

  10. .NET Core 学习笔记3——EF Core

    EF Core (EntityFramework Core)是实体关系映射(O/RM)数据库访问框架.这个模式的好处就是让开发人员可以用对象模型来操作数据库,这是一种对开发人员较为友好的方式. O/R ...