3. Django 初探路由

image-20240408131151503

3. 初探路由

一个完整的路由包含: 路由地址, 视图函数(或者视图类), 可选变量和路由命名.
本章讲述Django的路由编写规则与使用方法, 内容分为: 路由定义规则, 命名空间与路由命名, 路由的使用方式.

3.1 路由定义规则

路由称为URL (Uniform Resource Locator, 统一资源定位符), 也可以称为URLconf, 
是对可以从互联网上得到的资源位置和访问方法的一种简洁的表示, 是互联网上标准资源的地址.
互联网上的每个文件都有一个唯一的路由, 用于指出网站文件的路径位置.简单地说, 路由可视为我们常说的网址, 每个网址代表不同的网页.

3.1.1 Django 2以上版本路由定义

我们知道完整的路由包含: 路由地址, 视图函数(或者视图类), 可选变量和路由命名.
其中基本的信息必须有: 
路由地址和视图函数(或者视图类), 路由地址即我们常说的网址, 
视图函数(或者视图类)即App的views.py文件所定义的函数或类.在讲解路由定义规则之前, 需对MyDjango项目的目录进行调整, 使其更符合开发规范性.
在项目的index文件夹里添加一个空白内容的.py文件, 命为urls.py.
项目结构如图3-1所示.

2024-04-07_004335

2024-04-07_005145

在项目目录下的templates内创建index.html文件, 并在文件内添加如下代码:
<!-- templates的index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello World</title>
</head>
<body><span>Hello World!!</span>
</body>
</html>

image-20240407012432812

2024-04-07_005834

3-1 项目结构
在App(index文件夹)里添加urls.py是将所有属于App的路由都写入该文件中, 
这样更容易管理和区分每个App的路由地址, 而django3文件夹的urls.py是将每个App的urls.py统一管理.这种路由设计模式是Django常用的, 其工作原理如下:
(1) 运行Django项目时, Django从Django3文件夹的urls.py找到各个App所定义的路由信息, 生成完整的路由列表.
(2) 当用户在浏览器上访问某个路由地址时, Django就会收到该用户的请求信息.
(3) Django从当前请求信息获取路由地址, 并在路由列表里匹配相应的路由信息,再执行路由信息所指向的视图函数(或视图类), 从而完成整个请求响应过程.在这种路由设计模式下, MyDjango文件夹的urls.py代码如下所示:
from django.contrib import admin
from django.urls import path, includeurlpatterns = [# 指向内置Admin后台系统的路由文件sites.pypath('admin/', admin.site.urls),# 指向index的路由文件urls.pypath('', include('index.urls')),
]

2024-04-07_011314

Django3文件夹的urls.py定义两条路由信息, 分别是Admin站点管理和首页地址(index). 
其中, Admin站点管理在创建项目时已自动生成, 一般情况下无须更改; 首页地址是指index文件夹的urls.py.
django3文件夹的urls.py的代码解释如下:
 from django.contrib import admin: 导入内置Admin功能模块.
 from django.urls import path, include: 导入Django的路由函数模块.
 urlpatterns: 代表整个项目的路由集合, 以列表格式表示, 每个元素代表一条路由信息.
 path('admin/', admin.site.urls): 设定Admin的路由信息.'admin/'代表 127.0.0.1:8000/admin 的路由地址, admin后面的斜杠是路径分隔符, 其作用等同于计算机中文件目录的斜杠符号;admin.site.urls指向内置Admin功能所自定义的路由信息,可以在Python目录Lib\site-packages\django\contrib\admin\sites.py找到具体定义过程.
 path('', include('index.urls')): 路由地址为'\', : 127.0.0.1:8000 , 通常是网站的首页;路由函数include是将该路由信息分发给index的urls.py处理.由于首页地址分发给index的urls.py处理, 因此下一步需要对index的urls.py编写路由信息, 代码如下:
# index的urls.py
from django.urls import path
from . import views
urlpatterns = [path('', views.index)
]

2024-04-07_011512

index的urls.py的编写规则与django3文件夹的urls.py大致相同, 这是最为简单的定义方法,
此外还可以参考内置Admin功能的路由定义方法.在index的urls.py导入index的views.py文件, 该文件用于编写视图函数或视图类, 主要用于处理当前请求信息并返回响应内容给用户.
路由信息path('', views.index)的views.index是指视图函数index处理网站首页的用户请求和响应过程.因此, 在index的views.py中编写index函数的处理过程, 代码如下:
from django.shortcuts import renderdef index(request):value = 'This is test!'print(value)return render(request, 'index.html')

2024-04-07_011644

index函数必须设置一个参数, 参数命名不固定, 但常以request进行命名, 代表当前用户的请求对象, 
该对象包含当前请求的用户名, 请求内容和请求方式等.
视图函数执行完成后必须使用return将处理结果返回, 否则程序会抛出异常信息.启动MyDjango项目, 在浏览器里访问: 127.0.0.1:8000 , 运行结果如图3-2所示.

2024-04-07_012640

从上述例子看到, 当启动Django3项目时, Django会从配置文件settings.py读取属性ROOT_URLCONF的值,
默认值为django3.urls, 其代表django3文件夹的urls.py文件, 然后根据ROOT_URLCONF的值来生成整个项目的路由列表.路由文件urls.py的路由定义规则是相对固定的, 路由列表由urlpatterns表示, 每个列表元素代表一条路由.
路由是由Django的path函数定义的, 该函数第一个参数是路由地址, 第二个参数是路由所对应的处理函数(视图函数或视图类),
这两个参数是路由定义的必选参数.

3.1.2 Django 1.X路由定义

3.1.1小节介绍了Django 2以上版本的路由定义规则, 而Django 1版本是不支持这种定义方式的.
虽然本书讲解的是Django 3, 但是到目前为止,
Django 3还能兼容Django 1的路由定义规则, 因此读者也有必要掌握Django 1的路由定义规则.Django 1版本的路由定义规则是由Django的url函数定义的, 
url函数的第一个参数是路由地址, 第二个参数是路由所对应的处理函数, 这两个参数也是必选参数.而路由地址需设置路由符号^和$. 
^代表当前路由地址的相对路径; $代表当前路由地址的终止符.
我们分别改写项目的django3文件夹和index文件夹的urls.py文件, 使用Django 1版本的路由定义规则, 代码如下:
# MyDjango文件夹的urls.py
from django.contrib import admin
from django.conf.urls import url
from django.urls import includeurlpatterns = [# 指向内置Admin后台系统的路由文件sites.pyurl('admin/', admin.site.urls),# 指向index的路由文件urls.pyurl('^', include('index.urls')),
]

image-20240407013542165

# index文件夹的urls.py
from django.conf.urls import url
from . import viewsurlpatterns = [url('^$', views.index),url('^new/$', views.new)
]

image-20240407013446971

index文件夹的urls.py定义两条路由信息, 因此需要在index文件夹的views.py里定义相应的视图函数, 代码如下:
# index的views.py
from django.shortcuts import render
from django.http import HttpResponsedef index(request):return render(request, 'index.html')def new(request):return HttpResponse('This is new page')

image-20240407013757013

在django3文件夹的urls.py文件里, 
url('^', include('index.urls'))的路由符号^代表当前路由地址的相对地址, : http://127.0.0.1:8000.
该路由使用了Django的路由函数include, 它将路由交给index文件夹的urls.py完成路由定义.index文件夹的urls.py可以在: http://127.0.0.1:8000 的基础上定义多条路由.
上述代码定义了两条路由地址(127.0.0.1:8000127.0.0.1:8000/new/), 分别对应视图函数的index和new.
路由符号$代表路由地址的终止位置, 如果没有终止符号$, 那么在浏览器输入任意地址都能成功访问该路由地址.
以url('^new/$', views.new)为例, 若将终止符号$去掉, 则在浏览器访问: http://127.0.0.1:8000/new/XXX ,
其中XXX的内容不限, 这样的路由地址都符合url('^new/',views.new)定义规则, 从而执行视图函数new完成响应过程, 如图3-3所示.

2024-04-07_014845

2024-04-07_014551

2024-04-07_133447

3-3 终止符的作用
综上所述, Django 1的路由规则是使用Django的url函数实现路由定义, 并且路由地址设有路由符号^和$,
读者需要区分路由符号^和$的作用与使用规则, 在某程度上, 它比Django 2版本复杂并且代码可读性差,
因此Django 1的路由规则在Django 2版本里将逐渐淘汰.

3.1.3 路由变量的设置

在日常开发过程中, 有时一个路由可以代表多个不同的页面, 如编写带有日期的路由, 
若根据前面的编写方式, 按一年计算, 则需要开发者编写365个不同的路由才能实现, 这种做法明显是不可取的.因此, Django在定义路由时, 可以对路由设置变量值, 使路由具有多样性.
路由的变量类型有字符类型, 整型, slug和uuid, 最为常用的是字符类型和整型, 各个类型说明如下:
 字符类型: 匹配任何非空字符串, 但不含斜杠. 如果没有指定类型, 就默认使用该类型.
 整型: 匹配0和正整数.
 slug: 可理解为注释, 后缀或附属等概念, 常作为路由的解释性字符.可匹配任何ASCII字符以及连接符和下画线, 能使路由更加清晰易懂.比如网页的标题是'13岁的孩子', 其路由地址可以设置为'13-sui-de-hai-zi'.
 uuid: 匹配一个uuid格式的对象. 为了防止冲突, 规定必须使用'-'并且所有字母必须小写, 例如: 075194d3-6885-417e-a8a8-6c931e272f00.
根据上述变量类型, 在MyDjango项目的index文件夹的urls.py里新定义路由, 并且带有字符类型, 整型和slug的变量, 代码如下:
# index的urls.py
from django.urls import path
from . import viewsurlpatterns = [# 添加带有字符类型、整型和slug的路由path('<year>/<int:month>/<slug:day>', views.myvariable)
]

image-20240407134912091

在路由中, 使用变量符号'<>'可以为路由设置变量.
在括号里面以冒号划分为两部分, 冒号前面代表的是变量的数据类型, 冒号后面代表的是变量名, 
变量名可自行命名, 如果没有设置变量的数据类型, 就默认为字符类型.上述代码设置了3个变量, 分别是<year>, <int:month><slug:day>, 变量说明如下:
 <year>: 变量名为year, 数据格式为字符类型, <str:year>的含义一样.
 <int:month>: 变量名为month, 数据格式为整型.
 <slug:day>: 变量名为day, 数据格式为slug.
在上述新增的路由中, 路由的处理函数为myvariable, 因此在index的views.py中编写视图函数myvariable的处理过程, 代码如下:
# views.py的myvariable函数
from django.http import HttpResponsedef myvariable(request, year, month, day):return HttpResponse(str(year) + '/' + str(month) + '/'+str(day))

image-20240407135000102

视图函数myvariable有4个参数, 
其中参数year, month和day的参数值分别来自路由地址所设置的变量<year>, <int:month><slug:day>.
启动项目, 在浏览器上输入: 127.0.0.1:8000/2018/05/01 , 运行结果如图3-4所示.

2024-04-07_135508

3-4 运行结果
从上述例子可以看出, 路由地址所设置的变量可在视图函数里以参数的形式使用, 
视图函数myvariable将路由地址的变量值作为响应内容(2018/5/01)输出到网页上,
由于路由地址的3个变量类型分别是字符类型, 整型和slug, 因此路由地址的05转化为数字5.
(解释: URL本质上是一个文本字符串, 无论是字母, 数字还是其他特殊字符, 它们都是作为字符串的一部分来处理的.
月份的字符串05转为整形后变成5, 日期的字符串01被转为解释性字符类型后还是05.)
如果浏览器输入的路由地址与其变量类型不相符, Django就会提示Page not found, 比如将路由地址的05改为字母AA, 如图3-5所示.
(解释: AA无法转换为整形.)

image-20240407135806793

3-5 运行结果
路由的变量和视图函数的参数要一一对应, 如果视图函数的参数与路由的变量对应不上, 那么程序会抛出参数不相符的报错信息.
比如路由地址里设置了3个变量, 而视图函数myvariable仅设置两个路由变量的参数year和month, 
当再次访问网页的时候, 浏览器就会提示报错信息, 如图3-6所示.
# views.py的myvariable函数
from django.http import HttpResponsedef myvariable(request, year, month):return HttpResponse(str(year) + '/' + str(month))

2024-04-07_140115

3-6 运行结果	
除了在路由地址设置变量外, Django还支持在路由地址外设置变量(路由的可选变量).
我们在index的urls.py和views.py中分别新增路由和视图函数, 代码如下:
# index的urls.py
from django.urls import path
from . import viewsurlpatterns = [# 添加带有字符类型, 整型和slug的路由path('<year>/<int:month>/<slug:day>',views.myvariable),# 添加路由地址外的变量monthpath('', views.index, {'month': '2019/10/10'})
]
# index的views.py
from django.http import HttpResponsedef myvariable(request, year, month, day):return HttpResponse(str(year)+'/'+str(month)+'/'+str(day))def index(request, month):return HttpResponse('这是路由地址之外的变量: '+month)
从上述代码可以看出, 路由函数path的第3个参数是{'month': '2019/10/10'}, 该参数的设置规则如下:
 参数只能以字典的形式表示.
 设置的参数只能在视图函数中读取和使用.
 字典的一个键值对代表一个参数, 键值对的键代表参数名, 键值对的值代表参数值.
 参数值没有数据格式限制, 可以为某个实例对象, 字符串或列表(元组).
视图函数index的参数必须对应字典的键, 如果字典里设置两对键值对, 视图函数就要设置相应的函数参数,
否则在浏览器上访问的时候就会提示图3-6的报错信息.
最后重新运行MyDjango项目, 在浏览器上访问: 127.0.0.1:8000, 运行结果如图3-7所示.

image-20240407140802099

3-7 运行结果

3.1.4 正则表达式的路由定义

3.1.3小节的路由设置得知, 路由地址变量分别代表日期的年, , , 其变量类型分别是字符类型, 整型和slug,
因此在浏览器上输入: 127.0.0.1:8000/AAAA/05/01也是合法的, 但这不符合日期格式要求.

image-20240407180427204

为了进一步规范日期格式, 可以使用正则表达式限制路由地址变量的取值范围.
在index文件夹的urls.py里使用正则表达式定义路由地址, 代码如下:
# index的urls.py
from django.urls import re_path
from . import viewsurlpatterns = [re_path('(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2}).html',views.mydate)
]
路由的正则表达式是由路由函数re_path定义的, 其作用是对路由变量进行截取与判断, 正则表达式是以小括号为单位的,
每个小括号的前后可以使用斜杠或者其他字符将其分隔与结束.
以上述代码为例,, 分别将变量year, month和day以斜杠隔开, 每个变量以一个小括号为单位, 
在小括号内, 可分为3部分, (?P<year>[0-9]{4})为例。
 ?P是固定格式, 字母P必须为大写.
 <year>为变量名.
 [0-9]{4}是正则表达式的匹配模式, 代表变量的长度为4, 只允许取09的值.上述路由的处理函数为mydate函数, 因此还需要在index的views.py中编写视图函数mydate, 代码如下:
# views.py的mydate函数
from django.http import HttpResponsedef mydate(request, year, month, day):return HttpResponse(str(year)+'/'+str(month)+'/'+str(day))
启动MyDjango项目, 在浏览器上输入: 127.0.0.1:8000/2018/05/01.html 即可查看运行结果, 如图3-8所示.

image-20240407181147524

3-8 运行结果
路由地址的末端设置了'.html', 这是一种伪静态URL技术, 可将网址设置为静态网址, 用于SEO搜索引擎的爬取, 如百度, 谷歌等.
此外, 在末端设置'.html'是为变量day设置终止符, 
假如末端没有设置'.html', 在浏览器上输入无限长的字符串, 路由也能正常访问, 如图3-9所示.

2024-04-07_181415

3-9 运行结构

3.2 命名空间与路由命名

网站规模越大, 其网页的数量就会越多, 如果网站的网址过多, 在管理或者维护上就会存在一定的难度.
Django为了更好地管理和使用路由, 可以为每条路由设置命名空间或路由命名.

3.2.1 命名空间namespace

在MyDjango项目里创建新的项目应用user, 并且在user文件夹里创建urls.py文件,
然后在配置文件settings.py的INSTALLED_APPS中添加项目应用user,
使得Django在运行的时候能够识别项目应用user, 项目结构如图3-10所示.
# 1. 使用代码创建user应用
PS D:\django3> python manage.py startapp user 
# 2. 在配置文件中添加user应用
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','index.apps.IndexConfig','user',
]

image-20240407182323593

3. 在urls目录下创建urls.py文件.

2024-04-07_182439

3-10 目录结构
在MyDjango文件夹的urls.py中重新定义路由信息, 分别指向index文件夹的urls.py和user文件夹的urls.py, 代码如下:
from django.contrib import admin
from django.urls import path, includeurlpatterns = [# 指向内置Admin后台系统的路由文件sites.pypath('admin/', admin.site.urls),# 指向index的路由文件urls.pypath('', include(('index.urls', 'index'),namespace='index')),# 指向user的路由文件urls.pypath('user/', include(('user.urls', 'user'),namespace='user'))
]

image-20240407182747050

上述代码中, 新增的路由使用Django路由函数include并且分别指向index文件夹的urls.py和user文件夹的urls.py.
在函数include里设置了可选参数namespace, 该参数是函数include特有的参数, 这就是Django设置路由的命名空间.
路由函数include设有参数arg和namespace,
参数arg: 指向项目应用App的urls.py文件, 其数据格式以元组或字符串表示;
可选参数namespace: 是路由的命名空间. 若要对路由设置参数namespace, 则参数arg必须以元组格式表示, 并且元组的长度必须为2.
元组的元素说明如下: 
 第一个元素为项目应用的urls.py文件, 比如('index.urls', 'index')'index.urls', 这是代表项目应用index的urls.py文件.
 第二个元素可以自行命名, 但不能为空, 一般情况下是以项目应用的名称进行命名,('index.urls', 'index')'index'是以项目应用index进行命名的.如果路由设置参数namespace并且参数arg为字符串或元组长度不足2的时候, 
在运行django3的时候, Django就会提示错误信息, 如图3-11所示.

2024-04-07_183202

3-11 报错信息
下一步是分析路由函数include的作用, 它是将当前路由分配到某个项目应用的urls.py文件,
而项目应用的urls.py文件可以设置多条路由, 这种情况类似计算机上的文件夹A, 并且该文件夹下包含多个子文件夹,
而Django的命名空间namespace相当于对文件夹A进行命名.假设项目路由设计为: 在django3文件夹的urls.py新定义4条路由,
每条路由都使用路由函数include, 并分别命名为A, B, C, D, 每条路由对应某个项目应用的urls.py文件,
并且每个项目应用的urls.py文件里定义若干条路由.根据上述的路由设计模式, 将django3文件夹的urls.py视为计算机上的D盘, 
在D盘下有4个文件夹, 分别命名为A, B, C, D, 每个项目应用的urls.py所定义的若干条路由可视为这4个文件夹里面的文件.
在这种情况下, Django的命名空间namespace等同于文件夹A, B, C, D的文件名.
Django的命名空间namespace可以为我们快速定位某个项目应用的urls.py,
再结合路由命名name就能快速地从项目应用的urls.py找到某条路由的具体信息, 这样就能有效管理整个项目的路由列表.
(命名空间在总路由处为子路由设置了一个独特的标签或名称, 使得在整个应用程序中都可以通过这个标签或名称来引用和管理这些子路由.)
有关路由函数include的定义过程, 可以在Python安装目录下找到源码(Lib\site-packages\django\urls\conf.py)进行解读.

3.2.2 路由命名name

回顾3.2.1小节, 我们在django3文件夹的urls.py重新定义路由,
两条路由都使用路由函数include并且分别指向index文件夹的urls.py和user文件夹的urls.py,
命名空间namespace分别为index和user.
在此基础上, 我们在index文件夹的urls.py和user文件夹的urls.py中重新定义路由, 代码如下:
# index文件夹的urls.py
from django.urls import re_path, path
from . import viewsurlpatterns = [re_path('(?P<year>[0-9]{4}).html', views.mydate,name='mydate'),path('', views.index, name='index')
]
# user文件夹的urls.py
from django.urls import path
from . import viewsurlpatterns = [path('index', views.index, name='index'),path('login', views.userLogin, name='userLogin')
]

image-20240407184632118

每个项目应用的urls.py都定义了两条路由, 每条路由都由相应的视图函数进行处理,
因此在index文件夹的views.py和user文件夹的views.py中定义视图函数, 代码如下:
# index文件夹的views.py
from django.http import HttpResponse
from django.shortcuts import renderdef mydate(request, year):return HttpResponse(str(year))def index(request):return render(request, 'index.html')
# user文件夹的views.py
from django.http import HttpResponsedef index(request):return HttpResponse('This is userIndex')def userLogin(request):return HttpResponse('This is userLogin')

image-20240407192704974

运行程序(设置命名空间后,不同的命名空间内可以有相同的URL名称): 
输入地址: http://127.0.0.1:8000 访问index下的主页.
输入地址: http://127.0.0.1:8000/2018.html 访问index下的mydate页面.输入地址: http://127.0.0.1:8000/user/index 访问user下的主页.
输入地址: http://127.0.0.1:8000/user/login 访问user下的登录页面.
项目应用index和user的urls.py所定义的路由都设置了参数name, 这是对路由进行命名, 它是路由函数path或re_path的可选参数.
3.2.1小节的例子得知, 项目应用的urls.py所定义的若干条路由可视为D盘下的某个文件夹里的文件,
而文件夹的每个文件的命名是唯一的, 路由命名name的作用等同于文件夹里的文件名.如果路由里使用路由函数include, 就可以对该路由设置参数name, 
因为路由的命名空间namespace是路由函数include的可选参数, 而路由命名name是路由函数path或re_path的可选参数,
两者隶属于不同的路由函数, 因此可在同一路由里共存.
一般情况下, 使用路由函数include就没必要再对路由设置参数name, 尽管设置了参数name, 但在实际开发中没有实质的作用.
从index的urls.py和user的urls.py的路由可以看出, 不同项目应用的路由命名是可以重复的,
比如项目应用index和user皆设置了名为index的路由, 这种命名方式是合理的.在同一个项目应用里, 多条路由是允许使用相同的命名的, 但是这种命名方式是不合理的, 
因为在使用路由命名来生成路由地址的时候, Django会随机选取某条路由, 这样会为项目开发带来不必要的困扰.
综上所述, Django的路由命名name是对路由进行命名的, 
其作用是在开发过程中可以在视图或模板等其他功能模块里使用路由命名name来生成路由地址.在实际开发过程中, 我们支持使用路由命名, 
因为网站更新或防止爬虫程序往往需要频繁修改路由地址, 倘若在视图或模板等其他功能模块里使用路由地址, 
当路由地址发生更新变换时, 这些模块里所使用的路由地址也要随之修改, 这样就不利于版本的变更和维护; 
相对而言, 如果在这些功能模块里使用路由命名来生成路由地址, 就能避免路由地址的更新维护问题.

3.3 路由的使用方式

路由为网站开发定义了具体的网址, 不仅如此, 它还能被其他功能模块使用, 
比如视图, 模板, 模型, Admin后台或表单等, 本节将讲述如何在其他功能模块中优雅地使用路由.

3.3.1 在模板中使用路由

通过前面的学习, 相信读者对Django的路由定义规则有了一定的掌握.
路由经常在模板和视图中频繁使用, 举个例子, 
我们在访问爱奇艺首页的时候, 网页上会有各种各样的链接地址, 通过单击这些链接地址可以访问其他网页, 如图3-12所示.

2024-04-07_195426

3-12 爱奇艺首页
如果将图3-12当成一本书, 爱奇艺首页可作为书的目录, 通过书的目录就能快速找到我们需要阅读的内容;
同理, 网站首页的功能也是如此, 它的作用是将网站所有的网址一并显示.从网站开发的角度分析, 网址代表路由, 若想将项目定义的路由显示在网页上, 则要在模板上使用模板语法来生成路由地址.
Django内置了一套模板语法, 它能将Python的语法转换成HTML语言, 然后通过浏览器解析HTML语言并生成相应的网页内容.
将当前项目django3关闭, 之后将所有项目移走, 重新创建项目MyDjango, 创建index应用, 并在templates目录下创建index.html.

image-20240407200859112

打开MyDjango项目, 该项目仅有一个项目应用文件夹index和模板文件夹templates,
在index文件夹和模板templates文件夹中分别添加urls.py文件和index.html文件,
切勿忘记在配置文件settings.py中添加index文件夹和templates文件夹的配置信息.
项目结构如图3-13所示.

2024-04-07_201503

3-13 目录结构

2024-04-07_201632

项目环境搭建成功后, 在MyDjango文件夹的urls.py中使用路由函数path和include定义项目应用文件夹index的路由, 代码如下:
# MyDjango的urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [# 指向内置Admin后台系统的路由文件sites.pypath('admin/', admin.site.urls),# 指向index的路由文件urls.pypath('', include('index.urls')),
]

image-20240407202116435

在项目应用index里, 分别在urls.py和views.py文件中定义路由和视图函数;
并且在模板文件夹templates的index.html文件中编写模板内容, 代码如下:
# index的urls.py
from django.urls import path
from . import viewsurlpatterns = [# 添加带有字符类型、整型和slug的路由path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'),# 定义首页的路由path('', views.index)
]

image-20240407202748939

# index的views.py
from django.http import HttpResponse
from django.shortcuts import renderdef mydate(request, year, month, day):return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))def index(request):return render(request, 'index.html')

image-20240407202916577

<!-- templates的index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello World</title>
</head>
<body>
<span>Hello World!!</span>
<br>
<a href="{% url 'mydate' '2019' '01' '10' %}">查看日期</a>
</body>
</html>

image-20240407202848989

项目应用index的urls.py和views.py文件的路由和视图函数定义过程不再详细讲述.
我们分析index.html的模板内容, 模板使用了Django内置的模板语法url来生成路由地址, 模板语法url里设有4个不同的参数, 其说明如下:
 mydate: 代表命名为mydate的路由, 即index的urls.py设有字符类型, 整型和slug的路由.
 2019: 代表路由地址变量year, 它与mydate之间使用空格隔开.
 01: 代表路由地址变量month, 它与2019之间使用空格隔开.
 10: 代表路由地址变量day, 它与01之间使用空格隔开.
模板语法url的参数设置与路由定义是相互关联的, 具体说明如下:
 若路由地址存在变量, 则模板语法url需要设置相应的参数值, 参数值之间使用空格隔开.
 若路由地址不存在变量, 则模板语法url只需设置路由命名name即可, 无须设置额外的参数.
 若路由地址的变量与模板语法url的参数数量不相同, 则在浏览器访问网页的时候会提示NoReverseMatch at的错误信息, 如图3-14所示.

2024-04-07_204027

3-14 报错信息
从路由定义与模板语法url的使用对比发现, 路由所设置的变量month与模板语法url的参数'01'是不同的数据类型, 这种写法是允许的, 
因为Django在运行项目的时候, 会自动将模板的参数值转换成路由地址变量的数据格式.
运行MyDjango项目, 在浏览器访问127.0.0.1:8000并单击'查看日期'链接, 网页内容如图3-15所示.

2024-04-07_210912

3-15 网页内容
上述例子中, MyDjango文件夹的urls.py在使用函数include定义路由时并没有设置命名空间namespace.
若设置了命名空间namespace, 则模板里使用路由的方式有所变化.
下面对MyDjango文件夹urls.py和模板文件夹templates的index.html代码进行修改:
# MyDjango文件夹的urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [# 指向内置Admin后台系统的路由文件sites.pypath('admin/', admin.site.urls),# 指向index的路由文件urls.py# path('', include('index.urls')),# 使用命名空间namespacepath('', include(('index.urls', 'index'), namespace='index')),
]

image-20240407212240537

<!-- templates的index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello World</title>
</head>
<body><span>Hello World!!</span><br>{# <a href="{% url 'mydate' '2019' '01' '10' %}">查看日期</a>#}<a href="{% url 'index:mydate' '2019' '01' '10' %}">查看日期</a>
</body>
</html>

image-20240407212340628

从模板文件index.html可以看出, 若项目应用的路由设有命名空间namespace, 
则模板语法url在使用路由时, 需要在命名路由name前面添加命名空间namespace并且使用冒号隔开, 'namespace:name'.
若路由在定义过程中使用命名空间namespace, 而模板语法url没有添加命名空间namespace,
则在访问网页时, Django提示如图3-14所示的报错信息.
当Django模板引擎渲染这个模板时, 它会查找名为'index:mydate'的URL模式, 
并使用提供的参数('2019', '01', '10')来生成最终的URL.
这个生成的URL将替换{% url 'index:mydate' '2019' '01' '10' %}.

2024-04-08_123428

3.3.2 反向解析reverse与resolve

路由除了在模板里使用之外, 还可以在视图里使用.
我们知道Django的请求生命周期是指用户在浏览器访问网页时, Django根据网址在路由列表里查找相应的路由,
再从路由里找到视图函数或视图类进行处理, 将处理结果作为响应内容返回浏览器并生成网页内容.
这个生命周期是不可逆的, 而在视图里使用路由这一过程被称为反向解析.Django的反向解析主要由函数reverse和resolve实现: 
函数reverse是通过路由命名或可调用视图对象来生成路由地址的; 
函数resolve是通过路由地址来获取路由对象信息的.以MyDjango项目为例, 项目的目录结构不再重复讲述, 其结构与3.3.1小节的目录结构相同.
在MyDjango文件夹的urls.py和index文件夹的urls.py里定义路由地址, 代码如下:
# MyDjango文件夹的urls.py
from django.urls import path, includeurlpatterns = [# 指向index的路由文件urls.pypath('', include(('index.urls', 'index'), namespace='index')),
]

image-20240407215837871

# index文件夹的urls.py
from django.urls import path
from . import viewsurlpatterns = [# 添加带有字符类型、整型和slug的路由path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'),# 定义首页的路由path('', views.index, name='index')
]

image-20240407220038573

上述代码定义了项目应用index的路由信息, 路由命名分别为index和mydate, 路由定义过程中设置了命名空间namespace和路由命名name.
由于反向解析函数reverse和resolve常用于视图(views.py), 模型(models.py)或Admin后台(admin.py),
因此在视图(views.py)的函数mydate和index里分别使用reverse和resolve, 代码如下:
# index文件夹的views.py
from django.http import HttpResponse
from django.shortcuts import reverse
from django.urls import resolvedef mydate(request, year, month, day):args = ['2019', '12', '12']# 先使用reverse, 再使用resolveresult = resolve(reverse('index:mydate', args=args))print('kwargs:', result.kwargs)print('url_name:', result.url_name)print('namespace:', result.namespace)print('view_name:', result.view_name)print('app_name:', result.app_name)return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))def index(request):kwargs = {'year': 2010, 'month': 2, 'day': 10}args = ['2019', '12', '12']# 使用reverse生成路由地址(index是名称空间, mydate是路由模式)print(reverse('index:mydate', args=args))print(reverse('index:mydate', kwargs=kwargs))return HttpResponse(reverse('index:mydate', args=args))

image-20240407220348907

函数index主要使用反向解析函数reverse来生成路由mydate的路由地址.
为了进一步了解函数reverse, 我们在PyCharm下打开函数reverse的源码文件, 如图3-16所示.

image-20240407220607510

3-16 函数reverse
从图3-16看到, 函数reverse设有必选参数viewname, 其余参数是可选参数, 各个参数说明如下:
 viewname: 代表路由命名或可调用视图对象, 一般情况下是以路由命名name来生成路由地址的.
 urlconf: 设置反向解析的URLconf模块.默认情况下, 使用配置文件settings.py的ROOT_URLCONF属性(MyDjango文件夹的urls.py).
 args: 以列表方式传递路由地址变量, 列表元素顺序和数量应与路由地址变量的顺序和数量一致.
 kwargs: 以字典方式传递路由地址变量, 字典的键必须对应路由地址变量名, 字典的键值对数量与变量的数量一致.
 current_app: 提示当前正在执行的视图所在的项目应用, 主要起到提示作用, 在功能上并无实质的作用.
一般情况下只需设置函数reverse的参数viewname即可, 如果路由地址设有变量, 那么可自行选择参数args或kwargs设置路由地址的变量值.
参数args和kwargs不能同时设置, 否则会提示ValueError报错信息, 如图3-17所示.

2024-04-07_221600

3-17 ValueError报错信息
运行MyDjango项目, 在浏览器上访问: 127.0.0.1:8000 , 当前请求将由视图函数index处理,
该函数使用reverse来获取路由命名为mydate的路由地址并显示在网页上, 如图3-18所示.
(解释: reverse函数会查找index名称空间下名为mydate的URL模式, 
并使用提供的参数['2019', '12', '12']来填充URL模式( <year>/<int:month>/<slug:day> )中的占位符. )

2024-04-08_124607

3-18 网页内容
从网页内容得知, 路由地址: /2019/12/12 是一个相对路径, 
在Django中, 所有路由地址皆以相对路径表示, 地址路径首个斜杆'/'代表域名(127.0.0.1:8000).
接下来分析视图函数mydate, 它是在函数reverse的基础上使用函数resolve.
我们在PyCharm里打开函数resolve的源码文件, 如图3-19所示.

image-20240407230211259

3-19 函数resolve
从图3-19可以看到, 函数resolve设有两个参数, 参数path是必选参数, urlconf是可选参数, 参数说明如下:
 path: 代表路由地址, 通过路由地址来获取对应的路由对象信息.
 urlconf: 设置反向解析的URLconf模块.默认情况下, 使用配置文件settings.py的ROOT_URLCONF属性(MyDjango文件夹的urls.py).函数resolve是以路由对象作为返回值的, 该对象内置多种函数方法来获取具体的路由信息, 如表3-1所示.
函数方法说明
func路由的视图函数对象或视图类对象
args以列表格式获取路由的变量信息
kwargs以字典格式获取路由的变量信息
url_name获取路由命名name
app_name获取路由函数include的参数arg的第二个元素值
app_names与app_name功能一致, 但以列表格式表示
namespace获取路由的命名空间namespace
namespaces与namespace功能一致, 但以列表格式表示
view_name获取整个路由的名称, 包括命名空间
运行MyDjango项目, 在浏览器访问: 127.0.0.1:8000/2019/12/12 , 在PyCharm的下方查看函数resolve的对象信息, 如图3-20所示.

image-20240407230740701

3-20 函数resolve的对象信息
综上所述, 函数reverse和resolve主要是对路由进行反向解析, 通过路由命名或路由地址来获取路由信息.
在使用这两个函数的时候, 需要注意两者所传入的参数类型和返回值的数据类型.

3.3.3 路由重定向

重定向称为HTTP协议重定向, 也可以称为网页跳转, 它对应的HTTP状态码为301, 302, 303, 307, 308.
简单来说, 网页重定向就是在浏览器访问某个网页的时候, 这个网页不提供响应内容, 而是自动跳转到其他网址, 由其他网址来生成响应内容.
Django的网页重定向有两种方式: 
第一种方式是路由重定向;
第二种方式是自定义视图的重定向.
两种重定向方式各有优点, 前者是使用Django内置的视图类RedirectView实现的, 默认支持HTTP的GET请求;
后者是在自定义视图的响应状态设置重定向, 能让开发者实现多方面的开发需求.
我们在MyDjango项目里分别讲述Django的两种重定向方式, 在index的urls.py中定义路由turnTo, 其代码如下所示:
from django.urls import path
from . import views
from django.views.generic import RedirectViewurlpatterns = [# 添加带有字符类型、整型和slug的路由path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'),# 定义首页的路由path('', views.index, name='index'),# 设置路由跳转path('turnTo', RedirectView.as_view(url='/'), name='turnTo')
]

image-20240407234223132

在路由里使用视图类RedirectView必须使用as_view方法将视图类实例化, 
参数url用于设置网页跳转的路由地址, '/'代表网站首页(路由命名为index的路由地址).
然后在index的views.py中定义视图函数mydate和index, 代码如下:
from django.http import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import reversedef mydate(request, year, month, day):return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))def index(request):print(reverse('index:turnTo'))return redirect(reverse('index:mydate', args=[2019, 12, 12]))

image-20240407234401335

视图函数index是使用重定向函数redirect实现网页重定向的, 
这是Django内置的重定向函数, 其函数参数只需传入路由地址即可实现重定向.运行MyDjango项目, 在浏览器上输入: 127.0.0.1:8000/turnTo , 
发现该网址首先通过视图类RedirectView重定向首页(路由命名为index),
然后在视图函数index里使用重定向函数redirect跳转到路由命名为mydate的路由地址, 如图3-21所示.

2024-04-07_234715

3-21 网页重定向
从图3-21看到, 浏览器的开发者工具记录了3条请求信息, 其中名为turnTo的请求信息是我们在浏览器输入的网址,
而名为127.0.0.1的请求信息是网站首页, 两者的HTTP状态码都是302,
说明视图类RedirectView和重定向函数redirect皆能实现网站的重定向.以视图类RedirectView和重定向函数redirect的功能划分, 两者分别隶属于视图类和视图函数,
有关两者功能的实现过程和源码剖析将会分别在5.1.1小节和4.1.2小节详细讲述.

3.4 本章小结

路由称为URL, 也可以称为URLconf, 是对可以从互联网上得到的资源位置和访问方法的一种简洁的表示, 是互联网上标准资源的地址.
互联网上的每个文件都有一个唯一的路由, 用于指出网站文件的路径位置.
简单地说, 路由可视为我们常说的网址, 每个网址代表不同的网页.
路由基本编写规则如下(以MyDjango文件夹的urls.py为例):
 from django.contrib import admin: 导入内置Admin功能模块.
 from django.urls import path,include: 导入Django的路由功能模块.
 urlpatterns: 代表整个项目的路由集合, 以列表格式表示, 每个元素代表一条路由信息.
 path('admin/', admin.site.urls): 设定Admin的路由信息.其中'admin/'代表127.0.0.1:8000/admin的路由地址,admin后面的斜杠是路径分隔符, 其作用等同于计算机文件目录的斜杠符号;admin.site.urls指向内置Admin功能所定义的路由信息, 可在Python目录Lib\site-packages\django\contrib\admin\sites.py找到具体定义过程.
 path('', include('index.urls')): 路由地址为'\', 127.0.0.1:8000, 通常是网站的首页;路由函数include将该路由信息分发给index的urls.py处理.路由文件urls.py的路由定义规则是相对固定的, 路由列表由urlpatterns表示, 每个列表元素代表一条路由.
路由是由Django的path函数定义的, 该函数的第一个参数是路由地址, 第二个参数是路由所对应的处理函数(视图函数或视图类),
这两个参数是路由定义的必选参数.路由的变量类型有字符类型, 整型, slug和uuid, 最为常用的是字符类型和整型.
各个类型说明如下:
 字符类型: 匹配任何非空字符串, 但不含斜杠.如果没有指定类型, 就默认使用该类型.
 整型: 匹配0和正整数.
 slug: 可理解为注释, 后缀或附属等概念, 常作为路由的解释性字符, 可匹配任何ASCII字符以及连接符和下画线, 能使路由更加清晰易懂.比如网页的标题是'13岁的孩子', 其路由地址可以设置为'13-sui-de-hai-zi'.
 uuid: 匹配一个uuid格式的对象.为了防止冲突, 规定必须使用破折号并且所有字母必须小写, 例如: 075194d3-6885-417e-a8a8-6c931e272f00.除了在路由地址设置变量外, Django还支持在路由地址外设置变量(路由的可选变量),
比如在路由函数path或re_path中设置第3个参数, 其内容为{'month': '2019/10/10'}, 
该参数的设置规则如下:
 参数只能以字典的形式表示.
 设置的参数只能在视图函数中读取和使用.
 字典的一个键值对代表一个参数, 键值对的键代表参数名, 键值对的值代表参数值.
 参数值没有数据格式限制, 可以为某个对象, 字符串或列表(元组).路由的正则表达式是由路由函数re_path定义的, 其作用是对路由变量进行截取与判断, 
正则表达式是以小括号为单位的, 每个小括号的前后可以使用斜杠或者其他字符将其分隔与结束.
以上述代码为例, 分别将变量year, month和day以斜杠隔开, 
每个变量以一个小括号为单位, 在小括号内, 可分为3部分((?P<year>[0-9]{4})为例):
 ?P是固定格式, 字母P必须为大写.
 <year>为变量名.
 [0-9]{4}是正则表达式的匹配模式, 代表变量的长度为4, 只允许取09的值.命名空间namespace可以为我们快速定位某个项目应用的urls.py, 
再结合路由命名name就能快速地从项目应用的urls.py找到某条路由的具体信息, 这样就能有效管理整个项目的路由列表.Django的路由命名name是对路由进行命名, 其作用是在开发过程中可以在视图或模板等其他功能模块里使用路由命名name来生成路由地址.
模板语法url的参数设置与路由定义是相互关联的, 具体说明如下:
 若路由地址存在变量, 则模板语法url需要设置相应的参数值, 参数值之间使用空格隔开.
 若路由地址不存在变量, 则模板语法url只需设置路由命名name即可, 无须设置额外的参数.
 若路由地址的变量与模板语法url的参数数量不相同, 则在浏览器访问网页的时候会提示NoReverseMatch at的错误信息.Django的反向解析主要由函数reverse和resolve实现,
函数reverse是通过路由命名或可调用视图对象来生成路由地址的;
函数resolve是通过路由地址来获取路由对象信息的.
在使用这两个函数时, 需要注意两者所传入的参数类型和返回值的数据类型.Django的网页重定向有两种方式: 
第一种方式是路由重定向;
第二种方式是自定义视图的重定向.
两种重定向方式各有优点, 前者是使用Django内置的视图类RedirectView实现的, 默认支持HTTP的GET请求;
后者是在自定义视图的响应状态设置重定向, 能让开发者实现多方面的开发需求.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/301930.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯简单模板

目录 最大公约数 两个数的最大公约数 多个数的最大公约数 最小公倍数 两个数的最小公倍数 多个数的最小公倍数 素数 ​编辑 位数分离 正写 ​编辑 反写 闰年 最大公约数 两个数的最大公约数 之前看见的是辗转相除法&#xff0c;例如现在让算一个49&#xff0c;21…

该主机与 Cloudera Manager Server 失去联系的时间过长。 该主机未与 Host Monitor 建立联系

该主机与 Cloudera Manager Server 失去联系的时间过长。 该主机未与 Host Monitor 建立联系 这个去集群主机cm界面上看会出现这个错误 排查思路&#xff1a; 一般比较常见的原因可能是出问题的主机和集群主节点的时间对应不上了。还有就是cm agent服务出现问题了 去该主机的…

React - 你使用过高阶组件吗

难度级别:初级及以上 提问概率:55% 高阶组件并不能单纯的说它是一个函数,或是一个组件,在React中,函数也可以做为一种组件。而高阶组件就是将一个组件做为入参,被传入一个函数或者组件中,经过一定的加工处理,最终再返回一个组件的组合…

不使用 Docker 构建 Triton 服务器并在 Google Colab 平台上部署 HuggingFace 模型

Build Triton server without docker and deploy HuggingFace models on Google Colab platform EnvironmentBuilding Triton serverDeploying HuggingFace models客户端推荐阅读参考 Environment 根据Triton 环境对应表 &#xff0c;Colab 环境缺少 tensorrt-8.6.1&#xff0…

IP地址到底有什么用

IP地址在计算机网络中的作用至关重要&#xff0c;它不仅是设备在网络中的唯一标识&#xff0c;更是实现网络通信、网络管理和安全的关键要素。下面&#xff0c;我们将从多个方面详细阐述IP地址的作用。 首先&#xff0c;IP地址作为设备的唯一标识&#xff0c;为网络通信提供了…

再探Java为面试赋能(二)Java基础知识(二)反射机制、Lambda表达式、多态

文章目录 前言1.4 反射机制1.4.1 Class对象的获取1.4.2 Class类的方法1.4.3 通过反射机制修改只读类的属性 1.5 Lambda表达式1.5.1 函数式接口1.5.2 Lambda表达式的使用 1.6 多态1.6.1 多态的概念1.6.2 多态的实现条件1.6.3 重载&#xff08;Overload&#xff09;和重写&#x…

用Python+OpenCV截取视频中所有含有字幕的画面

1、需求背景 有的视频文件的字幕已经压制到了视频的图像中&#xff0c;不能单独提取出字幕文件。网上的 “提取视频字幕” 网站多为提取视频中的字幕文件&#xff0c;而非识别视频图像中的字幕。少数通过OCR技术识别画面中字幕的工具需要在线运行、运行速度较慢&#xff0c;或…

力扣2- 两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

前端layui自定义图标的简单使用

iconfont-阿里巴巴矢量图标库 2. 3. 4.追加新图标 5.文件复制追加新图标

TCP/IP协议、HTTP协议和FTP协议等网络协议简介

文章目录 一、常见的网络协议二、TCP/IP协议1、TCP/IP协议模型被划分为四个层次2、TCP/IP五层模型3、TCP/IP七层模型 三、FTP网络协议四、Http网络协议1、Http网络协议简介2、Http网络协议的内容3、HTTP请求协议包组成4、HTTP响应协议包组成 一、常见的网络协议 常见的网络协议…

DIY可视化UniApp表格组件

表格组件在移动端的用处非常广泛&#xff0c;特别是在那些需要展示结构化数据、进行比较分析或提供详细信息的场景中。数据展示与整理&#xff1a;表格是展示结构化数据的理想方式&#xff0c;特别是在需要展示多列和多行数据时。通过表格&#xff0c;用户可以轻松浏览和理解数…

vue 中使 date/time/datetime 类型的 input 支持 placeholder 方法

一般在开发时&#xff0c;设置了 date/time/datetime 等类型的 input 属性 placeholder 提示文本时&#xff0c; 发现实际展示中却并不生效&#xff0c;如图&#xff1a; 处理后效果如图&#xff1a; 处理逻辑 判断表单项未设置值时&#xff0c;则设置其伪类样式&#xff0c;文…

2024-04-08 NO.6 Quest3 自定义交互事件

文章目录 1 交互事件——更改 Cube 颜色2 交互事件——创建 Cube2.1 非代码方式2.2 代码方式 ​ 在开始操作前&#xff0c;我们导入上次操作的场景&#xff0c;相关介绍在 《2024-04-08 NO.5 Quest3 手势追踪进行 UI 交互-CSDN博客》 文章中。 1 交互事件——更改 Cube 颜色 …

知识管理系统|基于Springboot和vue的知识管理系统设计与实现(源码+数据库+文档)

知识管理 目录 基于Springboot和vue的知识管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台&#xff1a; 5.2.2 文章信息 5.3.1 论坛交流 2、后台 用户管理 5.1.2 文章分类 5.2.1 资料分类 四、数据库设计 五、核心代码 六、论文参考 七、最…

OpenHarmony实战:Combo解决方案之W800芯片移植案例

本方案基于OpenHarmony LiteOS-M内核&#xff0c;使用联盛德W800芯片的润和软件海王星系列Neptune100开发板&#xff0c;进行开发移植。 移植架构采用Board与SoC分离方案&#xff0c;支持通过Kconfig图形化配置编译选项&#xff0c;增加玄铁ck804ef架构移植&#xff0c;实现了…

老子云、AMRT3D、眸瑞科技

老子云概述 老子云3D可视化快速开发平台&#xff0c;集云压缩、云烘焙、云存储云展示于一体&#xff0c;使3D模型资源自动输出至移动端PC端、Web端&#xff0c;能在多设备、全平台进行展示和交互&#xff0c;是全球领先、自主可控的自动化3D云引擎。 平台架构 平台特性 1、基…

Java | Leetcode Java题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> quadruplets new ArrayList<List<Integer>>();if (nums null || nums.length < 4) {return…

spring cloud gateway openfeign 联合使用产生死锁问题

spring cloud gateway openfeign 联合使用产生死锁问题&#xff0c;应用启动的时候阻塞卡住。 spring.cloud 版本如下 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><vers…

【Leetcode每日一题】 递归 - 二叉树剪枝(难度⭐⭐)(50)

1. 题目解析 题目链接&#xff1a;814. 二叉树剪枝 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 想象一下&#xff0c;你有一堆层层叠叠的积木&#xff0c;你想从底部开始&#xff0c;把那些标记为0的积木拿走。如…

在线免费图像处理

功能 尺寸修改(自定义和内置常用的照片尺寸)图像压缩(比较好的情况最高可以压缩 10 倍, 如果是无损压缩可以压缩 5 倍左右,参数范围 50~70 左右)图像方向修改图像格式修改修改后的效果支持实时反馈, 并且支持点击图像预览,同时保留历史修改图片(在预览中可以查看)支持修改撤回…