专栏名称: 老齐Py
Data Science
目录
相关文章推荐
掌上长春  ·  周末旅行团——余晖暖忆暮程记⏳ ·  昨天  
掌上长春  ·  周末旅行团——余晖暖忆暮程记⏳ ·  昨天  
云南省文化和旅游厅  ·  惊喜云南 | 丽江东巴谷:打卡城市喧嚣外的 ... ·  昨天  
云南省文化和旅游厅  ·  惊喜云南 | 丽江东巴谷:打卡城市喧嚣外的 ... ·  昨天  
璞缇客精品酒店  ·  1.5h直达!比婺源更浪漫的金色秘境!乘船入 ... ·  5 天前  
51好读  ›  专栏  ›  老齐Py

【译】在Django中设置URL方法大全

老齐Py  · 掘金  ·  · 2020-02-07 06:27

正文

阅读 16

【译】在Django中设置URL方法大全

作者:Matt Layman

翻译:老齐


当用户访问网站的时候,其实是通过浏览器向网站发起访问请求,那么,网站是如何处理请求的?本文以Django框架为例进行说明,关于Django更详细的使用方法,请阅读《跟老齐学Python:Django实战(第二版)》。

来自浏览器的HTTP请求包含一个URL,URL描述Django应该生成哪些资源。由于URL可以有多种形式,我们必须把web应用可以处理的URL类型告诉Django,这就是URL配置的目的。在Django文档中,URL配置简称为URLconf。

URLconf在哪里?URLconf位于项目设置文件中的ROOT_URLCONF所设置的模块路径上。如果运行startproject命令,则该以project.url形式命名路由,其中“project”是项目名称。换句话说,URLconf就放在 project/urls.py 中,它与 settings.py 文件在同一个目录。

知道了文件所在的位置,但并没有讲它是如何工作的,下面来深入探索。

执行URLconf

可以将URL配置看作URL路径列表,Django会把这些路径从上到下进行匹配。当Django找到匹配的路径时,HTTP请求将转到与该路径相关联的Python代码块。这个“Python代码块”被称为视图,我们将在稍后对其进行更多的探讨。目前,请相信视图知道如何处理HTTP请求。

我们可以使用一个URLconf示例来实践上述观点。

# project/urls.py
from django.urls import path

from application import views

urlpatterns = [
    path("", views.home),
    path("about/", views.about),
    path("contact/", views.contact),
    path("terms/", views.terms),
]
复制代码

这里的内容与我上面的描述相吻合,Django对列表中的URL路径从上到下进行匹配。此列表的关键是 urlpatterns 。Django将把 urlpatterns 变量中的列表视为URLconf。

列表中的顺序也很重要,上述示例没有显示路径之间的任何冲突,但可以创建两个不同的 path ,它们可以匹配同一个URL,在后续内容中,会探究这个问题。

我们可以通过这个例子来看看它在www.itdiffer.com上是如何运行的。对于URLconf中的URL,Django不使用https://协议、或者主域名(www.itdiffer.com)及斜杠匹配路由,其他的都是URLconf所要匹配的。

  • 对https://www.itdiffer.com/about/匹配“about/”,并匹配第二个路径。该请求将转到 views.about 视图。
  • 对https://www.itdiffer.com/的请求匹配“”,并匹配第一个路径。该请求将路由到 views.home 视图。

补充说明:你可能注意到Django URL以斜杠结尾。事实上,如果你尝试访问像https://www.itdiffer.com/about这样的URL,Django会自动附加斜杠,再将请求重定向到相同的URL,这是因为使用了默认设置 APPEND_SLASH ,这种是Django在设计理念上的选择。

path 的作用

如果我给出的只是上面的例子,你可能会说:“哇,Django太笨了,为什么urlpatterns不是下面这样的字典?”

urlpatterns = {
    "": views.home,
    "about/": views.about,
    "contact/": views.contact,
    "terms/": views.terms,
}
复制代码

我不会因为你以上言论而苛责。

原因是 path 的能力更强大,大部分功能都在传给函数的第一个字符串参数中。 path 的字符串部分(例如,“about/”)称为路由。

正如你所看到的,路由可以是一个简单的字符串,它也可以包含一些转换特征,如此,就可以从URL中提取信息,并传给视图,例如这样的一个路径:

path("blog/<int:year>/<slug:slug>/", views.blog_post),
复制代码

此路径中的两个转换器是:

使用尖括号和一些保留关键词,让Django对URL进行解析,每个转换器都有一些预期的规则要遵循。

  • int必须与整数匹配。
  • slug必须与标称匹配。Slug是一种出现在Django中的报刊行话,因为Django是从堪萨斯州的一家报纸开始的。slug是一个字符串,它可以包含字符、数字、破折号和下划线。

考虑到这些转换器定义,让我们与一些URL进行比较!

现在我们可以重新审视一下之前的排序问题,以不同的顺序考虑这两条路径:

path("blog/<int:year>/", views.blog_by_year),
path("blog/2020/", views.blog_for_twenty_twenty),

# vs.

path("blog/2020/", views.blog_for_twenty_twenty),
path("blog/<int:year>/", views.blog_by_year),
复制代码

在第一次排序中,转换器将匹配blog/之后的任何整数,包括https://www.itdiffer.com/blog/2020/。这意味着第一次排序将永远不会调用 views.blog_for_twenty_twenty ,因为Django按顺序匹配路径。

相反,在第二次排序中,blog/2020/将正确地路由到 views.blog_for_twenty_twenty ,因为它首先匹配。这意味着这里有一个教训要谨记:

当包含与转换器范围匹配的路径项时,请确保将它们放在更具体的项之后。

视图简介

转换器如何处理这些从路径中捕获的参数?这很难在不触及视图的情况下解释,所以要对视图给予入门介绍,关于视图更详细的内容,还是要阅读《跟老齐学Python:Django实战(第二版)》的深入浅出讲解。

视图的作用是接受请求并返回响应,使用Python的可选类型检查,下面是一个发送Hello World响应的示例。

from django.http import HttpRequest, HttpResponse

def some_view(request: HttpRequest) -> HttpResponse:
    return HttpResponse('Hello World')
复制代码

Django将用户的HTTP请求封装在一个容器类中,这就是HttpRequest。同样,我们可以使用HttpResponse,以便让Django将我们的响应数据转换为格式正确的HTTP响应,并将其发送回用户的浏览器。

现在我们可以再看一个转换器。

    path("blog/<int:year>/", views.blog_by_year),
复制代码

路由中有了这个转换器, blog_by_year 会是什么样子?

# application/views.py
from django.http import HttpResponse

def blog_by_year(request, year):
    # ... some code to handle the year
    data = 'Some data that would be set by code above'
    return HttpResponse(data)
复制代码

Django开始在这里展示出一些不错的品质!转换器为我们做了一堆乏味的工作。Django设置的year参数已经是一个整数,因为Django进行了字符串解析和转换。

如果有人提交 /blog/not_a_number/ ,Django将返回 Not Found 响应,因为 not_a_number 不是整数。这样做的好处是,我们不必在 blog_by_year 中添加额外的检查逻辑来处理年份看起来不像数字的奇怪情况。这种函数可以节省时间!它使代码更干净,处理更精确。

怎样理解我们之前看到的另一个奇怪的例子 /blog/0/life-in-rome/ 呢?这将与前面部分中的模式相匹配,但假设我们希望匹配一个四位数的年份,我们该怎么做到呢?可以使用正则表达式。

路由中的正则表达式

在编程中,正则表达式应用很普遍,常常被比作电锯:功能强大得令人难以置信,但如果不小心的话,也可以砍掉“你的脚”。

正则表达式可以以非常简洁的方式表示复杂的关系和匹配模式,这种简洁性常常给正则表达式带来难以理解的坏名声。但如果小心使用,它们可以是很好的工具。

正则表达式(通常缩写为“regex”)适合于匹配字符串中的复杂模式。这听起来像是要解决前年提到的年份问题!在我们的问题中,只想匹配一个四位数的整数。让我们看看Django的解决方案,然后分解它的含义。







请到「今天看啥」查看全文