Django:URL调度器(三)(url csdn)
toyiye 2024-09-19 04:45 3 浏览 0 评论
URL 是 Uniform Resource Locator 的简写,统一资源定位符。 一个 URL 由以下几部分组成: scheme://host:port/path/?query-string=xxx#anchor
- scheme:代表的是访问的协议,一般为 http 或者 https 以及 ftp 等。
- host:主机名,域名,比如 https://www.toutiao.com 。
- port:端口号。当你访问一个网站的时候,浏览器默认使用80端口。
- path:查找路径。比如: https://docs.python.org/zh-cn/3/tutorial/venv.html ,后面的 zh-cn/3/tutorial/venv.html 就 是 path 。
- query-string:查询字符串,比如: www.baidu.com/s?wd=python ,后面的 wd=python 就是查 询字符串。
- anchor:锚点,后台一般不用管,前端用来做页面定位的。
注意: URL 中的所有字符都是 ASCII 字符集,如果出现非 ASCII 字符,比如中文,浏览器会进行编码再进行传输。
视图
视图一般都写在 app 的 views.py 中。并且视图的第一个参数永远都是request(一个HttpRequest)对象。这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等。在视图中,一般是完成逻辑相关的操作。比如这个请求是添加一篇博客,那么可以通过request来接收到这些数据,然后存储到数据库中,最后再把执行的结果返回给浏览器。视图函数的返回结果必须是HttpResponseBase 对象或者子类的对象。示例代码如下:
from django.http import HttpResponse
?
def articles_list(request):
return HttpResponse("文章列表!")
URL映射
视图写完后,要与URL进行映射,也即用户在浏览器中输入什么 url 的时候可以请求到这个视图函数。在用户输入了某个 url ,请求到我们的网站的时候, django 会从项目的 urls.py 文件中寻找对应的视图。在 urls.py 文件中有一个 urlpatterns 变量,以后 django 就会从这个变量中读取所有的匹配规则。匹配规则需要使用 django.urls.path 函数进行包裹,这个函数会根据传入的参数返回 URLPattern 或者是 URLResolver 的对象。示例代码如下:
from django.contrib import admin
from django.urls import path
from articles import views
?
urlpatterns = [
? ?path('admin/', admin.site.urls),
? ?path('articles/',views.articles_list)
]
URL中添加参数
有时候, url 中包含了一些参数需要动态调整。比如今日头条某篇文章的详情页的url,是 https://www.toutiao.com/i6779587855070003726/后面的 i6779587855070003726 就是这篇文章的 id ,那么今日头条的文章详情页面的url就可以写成https://www.toutiao.com/<id> ,其中id就是文章的id。那么如何在 django 中实现这种需求呢。这时候我们可以在 path 函数中,使用尖括号的形式来定义一个参数。比如我现在想要获取一篇文章的详细信息,那么应该在 url 中指定这个参数。示例代码如下:
from django.contrib import admin
from django.urls import path
from articles import views
?
urlpatterns = [
? ?path('admin/', admin.site.urls),
? ?path('articles/',views.articles_list),
? ?path('articles/<articles_id>/',views.articles_detail)
]
而 views.py 中的代码如下:
def articles_detail(request, articles_id):
? ?# 通过articles_id接收传入的参数
? ?text = "您输入的文章的id是:%s" % articles_id
? ?return HttpResponse(text)
当然,也可以通过查询字符串的方式传递一个参数过去。示例代码如下:
urlpatterns = [
? ?path('admin/', admin.site.urls),
? ?path('articles/',views.articles_list),
? ?path('articles/detail/',views.articles_detail)
]
在 views.py 中的代码如下:
def articles_detail(request):
? ?articles_id = request.GET.get("id")
? ?text = "您输入的文章id是:%s" % articles_id
? ?return HttpResponse(text)
以后在访问的时候就是通过 /articles/detail/?id=1 即可将参数传递过去。
被包含的URLconf 会收到来自父URLconf 捕获的任何参数,所以下面的例子是合法的:
# 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
包含其它的URLconfs
在我们的项目中,不可能只有一个 app ,如果把所有的 app 的 views 中的视图都放在 urls.py 中进行映射,肯定会让代码显得非常乱。因此 django 给我们提供了一个方法,可以在 app 内部包含自己的 url 匹配规则,而在项目的 urls.py 中再统一包含这个 app 的 urls 。 使用这个技术需要借助 include 函数。示例代码如下:
# django_study1/urls.py文件:
from django.contrib import admin
?
from django.urls import path,include
urlpatterns = [
? ?path('admin/', admin.site.urls),
? ?path('articles/',include("articles.urls"))
]
在 urls.py 文件中把所有的和 articles 这个 app 相关的 url 都移动到 app/urls.py 中了,然后在 django_study1/urls.py 中,通过 include 函数包含 articles.urls ,以后在请求 articles 相关的url的时候都需要加一个 articles 的前缀。
# articles/urls.py文件:
from django.urls import path
from . import views
? ?urlpatterns = [
? ?path('list/',views.articles_list),
? ?path('detail/<articles_id>/',views.articles_detail)
]
以后访问书的列表的 url 的时候,就通过 /articles/list/ 来访问,访问文章详情页面的 url 的时候就通过 articles/detail/<id> 来访问。
include这种方法可以用来去除URLconf 中的冗余,其中某个模式前缀被重复使用。例如,考虑这个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),
? ])),
]
path函数
path 函数的定义为:path(route,view,name=None,kwargs=None)。以下对这几个参数进行讲解。
- route 参数: url 的匹配规则。这个参数中可以指定 url 中需要传递的参数,比如在访问文章详情页的时候,可以传递一个 id 。传递参数是通过 <> 尖括号来进行指定的。并且在传递参数的时候,可以指定这个参数的数据类型,比如文章的 id 都是 int 类型,那么可以这样写<int:id> ,以后匹配的时候,就只会匹配到 id 为 int 类型的 url ,而不会匹配其他的 url ,并且在视图函数中获取这个参数的时候,就已经被转换成一个 int 类型了。其中还有几种常用的类型:str:匹配除了 '/' 之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串。int:匹配0或任何正整数。返回一个 int 。slug:匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签。比如,building-your-1st-django-site 。uuid:匹配一个格式化的 UUID 。为了防止多个 URL 映射到同一个页面,必须包含破折号并且字符都为小写。比如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID 实例。path:匹配非空的英文字符串,可以包含斜杠。
- view 参数:可以为一个视图函数或者是 类视图.as_view() 或者是 django.urls.include()函数的返回值。
- name 参数:这个参数是给这个 url 取个名字的,这在项目比较大, url 比较多的时候用处很大。
- kwargs 参数:有时候想给视图函数传递一些额外的参数,就可以通过 kwargs 参数进行传递。这个参数接收一个字典。传到视图函数中的时候,会作为一个关键字参数传过去。比如以下的 url 规则:
?from django.urls import path
?from . import views
?
?urlpatterns = [
path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}),
]
那么以后在访问 blog/1991/ 这个url的时候,会将 foo=bar 作为关键字参数传给 year_archive 函数。
re_path函数
有时候我们在写url匹配的时候,想要写使用正则表达式来实现一些复杂的需求,那么这时候我们可以使用 re_path 来实现。 re_path 的参数和 path 参数一模一样,只不过第一个参数也就是 route 参数可以为一个正则表达式。 一些使用 re_path 的示例代码如下:
from django.urls import path, re_path
from . import views
?
?
urlpatterns = [
? ?path('articless/2020/', views.special_case_2020),
? ?re_path(r'articless/(?P<year>[0-9]{4})/', views.year_archive),
? ?re_path(r'articless/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_archive),
? ?re_path(r'articless/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-_]+)/', views.articles_detail),
]
以上例子中我们可以看到,所有的 route 字符串前面都加了一个 r ,表示这个字符串是一个原生字符串。在写正则表达式中是推荐使用原生字符串的,这样可以避免在 python 这一层面进行转义。而且,使用正则表达式捕获参数的时候,是用一个圆括号进行包裹,然后这个参数的名字是通过尖括号 <year>进行包裹,之后才是写正则表达式的语法。
include函数
在项目变大以后,经常不会把所有的 url 匹配规则都放在项目的 urls.py 文件中,而是每个 app 都有自己的 urls.py 文件,在这个文件中存储的都是当前这个 app 的所有 url 匹配规则。然后再统一注册到项目的 urls.py 文件中。 include 函数有多种用法,这里讲下两种常用的用法。
- include(pattern,namespace=None):直接把其他 app 的 urls 包含进来。示例代码如下:
from django.contrib import admin
from django.urls import path,include
?
?
urlpatterns = [
? ? ? path('admin/', admin.site.urls),
? ? ? path('articles/',include("articles.urls"))
]
也可以传递 namespace 参数来指定一个实例命名空间,但是在使用实例命名空间之前,必须先指定一个应用命名空间。示例代码如下:
# 主urls.py文件:
from django.urls import path,include
?
?
urlpatterns = [
path('movie/',include('movie.urls',namespace='movie'))
]
然后在 movie/urls.py 中指定应用命名空间。实例代码如下:
from django.urls import path
from . import views
?
# 应用命名空间
app_name = 'movie'
?
?
urlpatterns = [
path('',views.movie,name='index'),
path('list/',views.movie_list,name='list'),
]
- include(pattern_list):可以包含一个列表或者一个元组,这个元组或者列表中又包含的是 path 或者是 re_path 函数。
- include((pattern,app_namespace),namespace=None):在包含某个 app 的 urls 的时候,可以指定命名空间,这样做的目的是为了防止不同的 app 下出现相同的 url ,这时候就可以通过命名空间进行区分。示例代码如下:
from django.contrib import admin
from django.urls import path,include
?
?
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/',include(("articles.urls",'articles')),namespace='articles')
]
但是这样做的前提是已经包含了应用命名空间。即在myapp.urls.py中添加一个和 urlpatterns 同级别的变量 app_name。
指定默认的参数
使用 path 或者是 re_path 的后,在 route 中都可以包含参数,而有时候想指定默认的参数,这时候可以通过以下方式来完成。示例代码如下:
from django.urls import path
from . import views
?
urlpatterns = [
? ?path('blog/', views.page),
? ?path('blog/page<int:num>/', views.page),
]
?
?
# View (in blog/views.py)
def page(request, num=1):
? ?# Output the appropriate page of blog entries, according to num.
? ...
当在访问 blog/ 的时候,因为没有传递 num 参数,所以会匹配到第一个url,这时候就执行 view.page 这个视图函数,而在 page 函数中,又有 num=1 这个默认参数。因此这时候就可以不用传递参数。而如果访问 blog/1 的时候,因为在传递参数的时候传递了 num ,因此会匹配到第二个 url ,这时候也会执行 views.page ,然后把传递进来的参数传给 page 函数中的 num 。
URL 的反向解析
之前我们都是通过url来访问视图函数。有时候我们知道这个视图函数,但是想反转回他的url。这时候就可以通过 reverse 来实现。
Django 提供执行反转 URL 的工具,这些工具与需要 URL 的不同层匹配:
- 在模板里:使用 url 模板标签。
- 在 Python 编码:使用 reverse() 函数。
- 在与 Django 模型实例的 URL 处理相关的高级代码中: get_absolute_url() 方法。
reverse("list")
> /articles/list/
如果有应用命名空间或者有实例命名空间,那么应该在反转的时候加上命名空间。示例代码如下:
reverse('articles:list')
> /articles/list/
如果这个url中需要传递参数,那么可以通过 kwargs 来传递参数。示例代码如下:
reverse("articles:detail",kwargs={"articles_id":1})
> /articles/detail/1
因为 django 中的 reverse 反转 url 的时候不区分 GET 请求和 POST 请求,因此不能在反转的时候添加查询字符串的参数。如果想要添加查询字符串的参数,只能手动的添加。示例代码如下:
login_url = reverse('login') + "?next=/"
自定义URL转换器
之前已经学到过一些django内置的 url 转换器,包括有int、 uuid等。有时候这些内置的 url转换器 并不能满足我们的需求,因此django给我们提供了一个接口可以让我们自己定义自己的url转换器。 自定义 url 转换器按照以下五个步骤来走就可以了:
- 定义一个类。
- 在类中定义一个属性 regex ,这个属性是用来保存 url 转换器规则的正则表达式。
- 实现to_python(self,value)方法,这个方法是将 url 中的值转换一下,然后传给视图函数 的。
- 实现 to_url(self,value)方法,这个方法是在做 url 反转的时候,将传进来的参数转换后拼 接成一个正确的url。
- 将定义好的转换器,注册到django中。
比如写一个匹配四个数字年份的 url 转换器。示例代码如下:
# 1. 定义一个类
class FourDigitYearConverter:
? ?# 2. 定义一个正则表达式
? ?regex = '[0-9]{4}'
? ?
? ?# 3. 定义to_python方法
? ?def to_python(self, value):
? return int(value)
? ?
? ?# 4. 定义to_url方法
? ?def to_url(self, value):
? return '%04d' % value
在 URLconf 中使用 register_converter() 来注册自定义的转换器类:
# 5. 注册到django中
from django.urls import register_converter
?
register_converter(converters.MyUrl, 'yyyy')
urlpatterns = [
? ?path('articless/2020/', views.special_case_2020),
? ?# 使用注册的转换器
? ?path('articless/<yyyy:year>/', views.year_archive),
...
]
官方文档:https://docs.djangoproject.com/zh-hans/3.0/topics/http/urls/
相关推荐
- 为何越来越多的编程语言使用JSON(为什么编程)
-
JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...
- 何时在数据库中使用 JSON(数据库用json格式存储)
-
在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...
- MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)
-
前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...
- JSON对象花样进阶(json格式对象)
-
一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...
- 深入理解 JSON 和 Form-data(json和formdata提交区别)
-
在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...
- JSON 语法(json 语法 priority)
-
JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...
- JSON语法详解(json的语法规则)
-
JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...
- MySQL JSON数据类型操作(mysql的json)
-
概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...
- JSON的数据模式(json数据格式示例)
-
像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...
- 前端学习——JSON格式详解(后端json格式)
-
JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...
- 什么是 JSON:详解 JSON 及其优势(什么叫json)
-
现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...
- PostgreSQL JSON 类型:处理结构化数据
-
PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...
- JavaScript:JSON、三种包装类(javascript 包)
-
JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...
- Python数据分析 只要1分钟 教你玩转JSON 全程干货
-
Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...
- 比较一下JSON与XML两种数据格式?(json和xml哪个好)
-
JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- r语言矩阵 (127)
- browsererror (114)
- exportexcel (119)
- cv2.bitwise_not (137)
- dump命令 (128)
- es6concat (126)
- heapify (127)
- java.security.egd (130)
- javax.annotation (117)
- jsstringsplit (117)
- js数字 (115)
- maven编译 (132)
- mysqlleft (128)
- nodejsbuffer (149)
- org.apache.commons.httpclient (126)
- org.jsoup (141)
- org.springframework.web (128)
- robotframework-ride (115)
- setnocounton (141)
- socket.gethostbyname (122)
- sqlmid (121)
- time.strptime (133)
- vscode格式化 (125)
- win32con (129)
- window.localstorage (126)