Django之路由配置(url与path及re_path区别)_django urlpatterns url和path-程序员宅基地

技术标签: django  Django  后端  

url是Django 1.x中的写法,在Django2.1中,开始舍弃Django1.x中的url写法。在Django2.x中,描写url配置的有两个函数path和re_path,re_path()函数可以看做是django 1.x中得url函数,即可以在路径中使用正则。

默认url(route, view, kwargs=None, name=None)

默认path(route, view, kwargs=None, name=None)

默认re_path(route, view, kwargs=None, name=None)

本文重点描述path和re_path,前五条内容即可实现基本运用

1、概述

要设计应用程序的URL,可以创建一个非正式的称为URLconf(URL配置)的Python模块。此模块是纯Python代码,是URL路径表达式与Python函数(您的视图)之间的映射。该映射可以根据需要短或长。它可以引用其他映射。并且,因为它是纯Python代码,所以它可以动态构造。

2、django如何处理请求

当用户请求一个页面时,Django根据下面的逻辑执行操作:

(1)决定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但是如果传入的HttpRequest对象具有urlconf属性(由中间件设置),则其值将被用于代替ROOT_URLCONF设置。
(2)加载该模块并寻找可用的urlpatterns。 它是django.conf.urls.url()实例的一个列表。
(3)依次匹配每个URL模式,在与请求的URL相匹配的第一个模式停下来。(注意url在列表中的位置)
(4)导入并调用匹配行中给定的视图,该视图是一个简单的Python函数(被称为视图函数),或基于类的视图。 视图将获得如下参数:
    <1>一个HttpRequest 实例。
    <2>如果匹配的正则表达式返回了没有命名的组,那么正则表达式匹配的内容将作为位置参数提供给视图。
    <3>关键字参数由正则表达式匹配的命名组组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖。
    <4>如果没有匹配到正则表达式,或者过程中抛出异常,将调用一个适当的错误处理视图。

3、转换器(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:slug>/', views.article_detail),
    ]
/articles/2005/03/ 将匹配第三条,并调用views.month_archive(request, year=2005, month=3)/articles/2003/匹配第一条,并调用views.special_case_2003(request)/articles/2003将一条都匹配不上,因为它最后少了一个斜杠,而列表中的所有模式中都以斜杠结尾;
/articles/2003/03/building-a-django-site/ 将匹配最后一个,并调用views.article_detail(request, year=2003, month=3, slug="building-a-django-site"

注意:

(1)要捕获一段url中的值,需要使用尖括号,而不是之前的圆括号;
(2)可以转换捕获到的值为指定类型,比如例子中的int。默认情况下,捕获到的结果保存为字符串类型,不包含/这个特殊字符;
(3)匹配模式的最开头不需要添加/,因为默认情况下,每个url都带一个最前面的/。

默认情况下,Django内置下面的路径转换器:

str:匹配任何非空字符串,但不含斜杠/,如果你没有专门指定转换器,那么这个是默认使用的;
int:匹配0和正整数,返回一个int类型
slug:可理解为注释。该转换器匹配任何ASCII字符以及连接符和下划线,比如’ building-your-1st-django-site‘;
uuid:匹配一个uuid格式的对象。为了防止冲突,规定必须使用破折号,所有字母必须小写,例如’075194d3-6885-417e-a8a8-6c931e272f00‘ 。返回一个UUID对象;
path:匹配任何非空字符串,重点是可以包含路径分隔符’/‘。这个转换器可以帮助你匹配整个url而不是一段一段的url字符串。

4、使用正则表达式

如果路径和转换器语法不足以定义URL模式,则也可以使用正则表达式。使用 re_path()代替path()。

在Python正则表达式中,已命名正则表达式组的语法为(?Ppattern),其中name是组的名称,并且 pattern是要匹配的某种模式。

示例URLconf,使用正则表达式重写:

from django.urls import path, re_path

from . import views

urlpatterns = [
    path('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<slug>[\w-]+)/$', views.article_detail),
]

与示例URLconf区别:

(1)将要匹配的确切URL受到更多限制。例如,年份10000将不再匹配,因为年份整数被限制为正好是四位数长。
(2)无论正则表达式进行哪种匹配,每个捕获的参数都将作为字符串发送到视图。
(3)当从使用re_path()切换为使用path(), re_path()反之亦然时,特别重要的是要注意视图参数的类型可能会发生变化,因此您可能需要调整视图。
(4)当命名的组与未命名的组两种样式混合使用时,任何未命名分组path('(\d+)/',view)都会被忽略,只有命名分组path('(?P<year>\d+)/',view)才会传递到视图函数。
(5)未命名分组将正则表达式匹配到的内容当作位置参数,命名分组将正则表达式匹配到的内容当作关键字参数

5、include()

在任何时候,urlpatterns都可以“include”其他URLconf模块。这本质上是一组位于其他url之下的“roots”。

from django.urls import include, path

urlpatterns = [
    path('community/', include('aggregator.urls')),
    path('contact/', include('contact.urls')),
]

每当Django遇到时include(),它都会截断直到该处匹配的URL的任何部分,并将剩余的字符串发送到包含的URLconf中以进行进一步处理。

另一种可能性是通过使用path()实例列表包括其他URL模块 。例如,考虑以下URLconf:

from django.urls import include, path

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    path('reports/', credit_views.report),
    path('reports/<int:id>/', credit_views.report),
    path('charge/', credit_views.charge),
]

urlpatterns = [
    path('', main_views.homepage),
    path('help/', include('apps.help.urls')),
    path('credit/', include(extra_patterns)),
]

/credit/reports/将由credit_views.report()视图处理 。

可用于从URLconf中删除重复使用单个模式前缀的冗余。

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),
    ])),
]
                    以下为深入了解内容

6、注册自定义路径转换器

对于更复杂的匹配要求,您可以定义自己的路径转换器。

转换器是包含以下内容的类:

一个regex类属性,作为一个字符串。
一个to_python(self, value)方法,用于将匹配的字符串转换为应该传递给视图函数的类型。如果它不能转换给定的值,就会引发ValueError。ValueError被解释为没有匹配,因此404响应被发送给用户,除非另一个URL模式匹配。
一个to_url(self, value)方法,用于将Python类型转换为要在URL中使用的字符串。
class FourDigitYearConverter:
    regex = '[0-9]{4}'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return '%04d' % value

使用register_converter()以下命令在URLconf中注册自定义转换器类 :

from django.urls import path, register_converter
from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<yyyy:year>/', views.year_archive),
    ...
]

7、URLconf匹配的内容

URLconf按照正常的Python字符串匹配请求的URL。不包括GET或POST参数或域名及请求方法。

例如,在对的请求中https://www.example.com/myapp/,URLconf将寻找myapp/。

在请求中https://www.example.com/myapp/?page=3,URLconf将寻找myapp/。

8、为视图参数指定默认值

一个方便的技巧是为视图的参数指定默认参数。这是一个示例URLconf和视图:

from django.urls import path

from . import views

urlpatterns = [
    path('blog/', views.page),
    path('blog/page<int:num>/', views.page),
]

两个URL模式都指向同一个视图 views.page,但是第一个模式没有从URL中捕获任何内容。如果第一个模式匹配,该page()函数将使用它的默认参数num;如果第二个模式匹配, page()将使用num捕获的任何值。

9、自定义错误视图

当Django无法找到所请求URL的匹配项时,或者引发异常时,Django会调用默认错误视图,Django中的默认错误视图对于大多数Web应用程序来说已经足够了,但是如果您需要任何自定义行为,可以在您的根URLconf中设置这些值,在任何其他URLconf中设置这些变量将无效。
值必须是可调用的,或者是表示视图的完整Python导入路径的字符串,应该调用该视图来处理当前的错误情况。

该page_not_found()视图被覆盖 handler404:

handler404 = 'mysite.views.my_custom_page_not_found_view'

该server_error()视图被覆盖 handler500:

handler500 = 'mysite.views.my_custom_error_view'

该permission_denied()视图被覆盖 handler403:

handler403 = 'mysite.views.my_custom_permission_denied_view'

该bad_request()视图被覆盖 handler400:

handler400 = 'mysite.views.my_custom_bad_request_view'

10、捕捉的参数

包含的URLconf从父URLconfs接收任何捕获的参数,:

# In settings/urls/main.py
from django.urls import include, path

urlpatterns = [
    path('<username>/blog/', include('foo.urls.blog')),
]

# In foo/urls/blog.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.blog.index),
    path('archive/', views.blog.archive),
]

在上面的示例中,捕获的"username"变量按预期传递给了include的URLconf。

11、传递额外的选项到函数

URLconfs有一个钩子,可让您将额外的参数作为Python字典传递给视图函数。

该path()函数可以使用可选的第三个参数,该参数应该是传递给view函数的额外关键字参数的字典。

from django.urls import path
from . import views

urlpatterns = [
    path('blog/<int:year>/', views.year_archive, {
    'foo': 'bar'}),
]

在此示例中,对于的请求/blog/2005/,Django将调用views.year_archive(request, year=2005, foo=‘bar’)
该技术在联合框架中用于将元数据和选项传递给视图。

注:URL模式可能会捕获命名的关键字参数,并且还会在其额外参数的字典中传递具有相同名称的参数。发生这种情况时,将使用字典中的参数代替URL中捕获的参数。

同样,您可以将额外选项传递给include(),所包含的URLconf中的每一行都将传递额外选项。

例如,这两个URLconf集在功能上是相同的:

设置一:

# main.py
from django.urls import include, path

urlpatterns = [
    path('blog/', include('inner'), {
    'blog_id': 3}),
]

# inner.py
from django.urls import path
from mysite import views

urlpatterns = [
    path('archive/', views.archive),
    path('about/', views.about),
]

设置二:

# main.py
from django.urls import include, path
from mysite import views

urlpatterns = [
    path('blog/', include('inner')),
]

# inner.py
from django.urls import path

urlpatterns = [
    path('archive/', views.archive, {
    'blog_id': 3}),
    path('about/', views.about, {
    'blog_id': 3}),
]

请注意,无论视图实际上是否接受这些选项,额外的选项将始终传递到所包含的URLconf中的每一行。因此,仅当您确定所包含的URLconf中的每个视图都接受要传递的额外选项时才有用。

12、URL的反向解析

在Django项目上进行工作时,通常需要获取最终形式的URL,以嵌入生成的内容(视图和资产URL,向用户显示的URL等)或在服务器上处理导航流程侧面(重定向等)

Django提供了一个解决方案,使得URL映射器是URL设计的唯一存储库。将其与URLconf一起提供,然后可以在两个方向上使用它:

(1)从用户/浏览器请求的URL开始,它将调用正确的Django视图,以提供可能需要的任何参数以及从URL中提取的值。
(2)从标识相应的Django视图以及将传递给该视图的参数值开始,获取关联的URL。

上述(2)是所谓的URL反向解析,反向URL匹配,反向URL查找或简称URL反向。

Django提供了执行URL反转的工具,这些工具与需要URL的不同层相匹配:

在模板中:使用url模板标记
在Python代码中:使用reverse()函数
在与Django模型实例的URL处理有关的更高级别的代码中:get_absolute_url()方法

再次考虑以下URLconf条目:

from django.urls import path

from . import views

urlpatterns = [
    path('articles/<int:year>/', views.year_archive, name='news-year-archive'),
]

可以使用以下模板代码获取它们:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{
    # Or with the year in a template context variable: #}
<ul>
{
    % for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{
    {
     yearvar }} Archive</a></li>
{
    % endfor %}
</ul>

在Python代码中:

from django.http import HttpResponseRedirect
from django.urls import reverse

def redirect_to_year(request):
    year = 2006
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

13、嵌套参数

正则表达式允许嵌套参数,而Django会解析它们并将其传递给视图。反转时,Django将尝试填写所有外部捕获的参数,而忽略任何嵌套的捕获参数。考虑以下URL模式,这些URL模式可以选择采用page参数:

from django.urls import re_path

urlpatterns = [
    re_path(r'^blog/(page-(\d+)/)?$', blog_articles),                  # bad
    re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?$', comments),  # good
]

这两种模式都使用嵌套的参数并将解析:例如,blog/page-2/将导致与blog_articles的匹配,其中包含两个位置参数:page-2/和2。第二种模式将comments/page-2/与关键字参数page_number设置为2匹配。在本例中,外部参数是一个非捕获参数。
blog_articles视图需要反转最外层捕获的参数,在本例中是page-2/或无参数,而comments可以反转,既不需要参数,也不需要page_number的值。
嵌套捕获的参数在视图参数和URL之间创建了一个强耦合,正如blog_articles所示:视图接收URL的一部分(page-2/),而不是只接收视图想要的值。这种耦合在反转时更加明显,因为要反转视图,我们需要传递URL片段而不是页码。

只捕获视图需要处理的值,并在正则表达式需要参数而视图忽略参数时使用非捕获参数。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44870139/article/details/105565242

智能推荐

Python与C++语法比较--字符串篇_python中字符串与c字符串区别-程序员宅基地

文章浏览阅读922次,点赞2次,收藏3次。-_python中字符串与c字符串区别

【干货】史蕾:大数据征信时代的个人信息保护-程序员宅基地

文章浏览阅读237次。嘉宾介绍:史蕾:1998年毕业于复旦大学国际经济法专业,现柏杨云天(北京)企业咨询有限公司,合伙人。曾就职于纳斯达克B2B上市公司环球资源(NDSDAQ:GSOL)和奇虎360法务部。密切关注大数据企业和大数据产品的创新性业务实践,为多家大数据公司产品合规分析、用户协议拟定、个人数据保护和隐私政策的制定、股权激励项目提供专项咨询意见。讲座全文:..._大数据征信评分机制对个人金融信息的保护问题

状态设计模式_状态机设计模式-程序员宅基地

文章浏览阅读3.8k次。状态模式是状态机的一种实现方式即可。状态机又叫有限状态机,它有3个部分组成:状态、事件、动作。其中,事件也称为转移条件。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。状态机的三种实现方式第一种实现方式叫分支逻辑法。利用if-else或者分支逻辑,参照状态转移图,将每一个状态转移原模原样地直译成代码。对于简单的状态机来说,这种实现方式最简单、最直接,是首选。第二种实现方式叫查表法。对于状态很多、状态转移比较复杂的状态机来说,查表法比较合适。_状态机设计模式

电脑基础字母和基础生成链接教训_/know/search.php?kw=%e5%8d%ab%e5%86%95%e5%86%a0%e5-程序员宅基地

文章浏览阅读3.2w次。电脑基础字母和基础生成链接教训http://www.sina.com.cn/mid/search.shtml?q=%E9%93%B6%E9%92%BB%E5%A8%B1%E4%B9%90%E7%94%B5%E8%AF%9D%E6%8A%95%E6%B3%A8%5F%E7%94%B5l7508834474http://www.sina.com.cn/mid/search.shtml?q=%E8%85%BE%E9%BE%99%E5%A8%B1%E4%B9%90%E7%94%B5%E8%AF%9D%E6%8A_/know/search.php?kw=%e5%8d%ab%e5%86%95%e5%86%a0%e5%86%9b

Python所有方向的学习路线图-程序员宅基地

文章浏览阅读960次,点赞24次,收藏16次。比自己单纯的自学效果好很多,不至于看到什么就学什么,容易走弯路,造成重复学习,时间和精力都浪费了,但是学到的东西却是有限的,还有一点就是你自己有这个学习路线,就能明确的知道目前的进度,以及自己的目标,这样就算中间你有事情耽误了,也不会影响你的学习。对于新手小白学习python的时候,这个时候基础是非常重要的,因为如果你没有基础,在后的学习过程中直接去学习某个方向的话,你将会一脸懵逼,所以基础是绕不开的,就跟盖房子需要打地基一样的,打好基础,你就无障碍的进行后面的学习了。5.Python Web后端开发。

jmeter组件四:PerfMon_Metrics_Collector(实时监听服务器资源)_windows版jmeter,perfmon metrics collector的端口设置-程序员宅基地

文章浏览阅读4.6k次。很多时候,我们进行性能的测试,都需要对服务器的性能进行测试,例如cpu,内存之类的注意:该组件仅适用于jmeter r3.1及以下版本使用一:下载必备组件1、在https://jmeter-plugins.org/wiki/PerfMonAgent/下载ServerAgent-2.2.1.zip,将ServerAgent-2.2.1.jar上传到被测服务器,解压可以直接运行 (Windo..._windows版jmeter,perfmon metrics collector的端口设置

随便推点

python创意turtle作品和代码,python turtle创意绘图-程序员宅基地

文章浏览阅读353次,点赞4次,收藏8次。前段时间,【草莓熊python turtle绘图代码】一文弄得我心情多少有点灰灰,此版草莓熊是我应某网友请求画的,当时只是想找个地方放代码给他,没想到访问量使用量会有那么多,抖音b站等等到处都是我画的草莓熊, 就连CSDN都有几个盗我代码(他们删除了作者版权信息部分)当成自己原创,还都上了CSDN首页热门推荐。python简单代码游戏。。更有甚者,居然有人拿我草莓熊代码来卖钱!!!请记住,不要下载和购买这种代码(包括可执行的exe文件,小心代码被篡改有病毒)我的代码是完整源代码,

自动辅助语音烟雾排风系统_asrpro5v与3.3v两个-程序员宅基地

文章浏览阅读396次。最近由于门市的厨房的老式油烟机估计时间久咯,风力不大咯,就想着做一款能根据油烟、水蒸气变化而自动控制换气风扇的设备。根据TVOC传感器选择不一样,就有两种版本:普通版(不含显示空气质量具体数值)、进阶版(显示具体数据)。_asrpro5v与3.3v两个

YOLOv5遇到问题_git_info = check_git_info()-程序员宅基地

文章浏览阅读1k次。学习yolov5遇见问题_git_info = check_git_info()

python如何封装成可调用的库_Python实现打包成库供别的模块调用-程序员宅基地

文章浏览阅读2.6k次。1.创建python项目bricewulib2.新建test_package包并创建info1类以及print_hello方法3.为了让包的结构再复杂点,我们再在test_package下面新建一个test_package2包并创建Info2类以及print_hello2方法(注意:这里是Info2,不是上面的Info1)4.此时整个test_package编写完成,目录结构(test_packa..._python如何封装成可调用的库

JDBC的执行流程-程序员宅基地

文章浏览阅读2.9k次,点赞5次,收藏11次。第二部:获取连接[建立与数据库的连接](表示jvm的进程和数据库进程之间的通道打开了,属于进程间通讯,是重量级的,使用完之后一定要关闭通道)第六步:释放资源、关闭连接(使用完资源之后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要关闭)第五步:处理查询结果集(只有第四步执行的是select语句的时候才有第五步,如果不是select语句直接到第六步)第一步:注册驱动(告诉Java程序即将连接的是哪个数据库)第三步:获取数据库操作对象(专门执行sql语句的对象)_jdbc的执行流程

java中的高并发-程序员宅基地

文章浏览阅读468次。这个大概可以作为一个继续深究下去的引子。首先得先理解并发与并行的含义,并行其实指的是串行并行,程序A和程序B交替执行,而从计算机cpu的执行时间来说,从人的感受上来说,就像是并行。而并行一般就是在多核cpu的环境下,多个任务在同一时间在执行。另外一个要清楚的概念就是,进程与线程的概念,进程是计算机资源分配和调度的最小单位,而线程是程序执行和调度的最小单位,进程就像是一间房子,这个房子里..._java中的高并发