栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django(五):路由

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django(五):路由

django-路由
      • 路由分发
      • 路由参数
      • 使用正则表达式
        • 正则路径中的无名分组
        • 正则路径中的有名分组
      • 反向解析
      • 命名空间
      • 错误处理

参考菜鸟教程(https://www.runoob.com/django/django-routers.html)和 django官方文档

路由分发

存在问题 :Django 项目里多个app目录共用一个 urls 容易造成混淆,后期维护也不方便。

解决 :使用路由分发(include),让每个app目录都单独拥有自己的 urls。

步骤:

  • 1、在每个 app 目录里都创建一个 urls.py 文件。(注意:命名必须是urlpatterns,否则无法引入)
  • 2、在项目名称目录下的 urls 文件里,统一将路径分发给各个 app 目录。

实例

from django.contrib import admin
from django.urls import path,include # 从 django.urls 引入 include
urlpatterns = [
    path('admin/', admin.site.urls),
    path("app01/", include("app01.urls")),
    path("app02/", include("app02.urls")),
]

路由参数

下面的路径转换器在默认情况下是有效的:

  • str - 匹配除了 ‘/’ 之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串。
  • int - 匹配 0 或任何正整数。返回一个 int 。
  • slug - 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签。比如,building-your-1st-django-site 。
  • uuid - 匹配一个格式化的 UUID 。为了防止多个 URL 映射到同一个页面,必须包含破折号并且字符都为小写。比如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID 实例。
  • path - 匹配非空字段,包括路径分隔符 ‘/’ 。它允许你匹配完整的 URL 路径而不是像 str 那样匹配 URL 的一部分。
    path('articles////', views.article_detail),
  • 要从 URL 中取值,使用尖括号。
  • 捕获的值可以选择性地包含转换器类型。比如,使用 来捕获整型参数。如果不包含转换器,则会匹配除了 / 外的任何字符。
  • 这里不需要添加反斜杠,因为每个 URL 都有。比如,应该是 articles 而不是 /articles 。

参数默认值

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

# View (in blog/views.py)
def page(request, num=1):
使用正则表达式
re_path(r'^articles/(?P[0-9]{4})/$', views.year_archive),
  • 将要匹配的 URLs 将稍受限制。比如,10000 年将不在匹配,因为 year 被限制长度为4。
  • 无论正则表达式进行哪种匹配,每个捕获的参数都作为字符串发送到视图。
正则路径中的无名分组

无名分组按位置传参,一一对应。

views 中除了 request,其他形参的数量要与 urls 中的分组数量一致。

# urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path("^index/([0-9]{4})/$", views.index),
]
# views.py
from django.shortcuts import HttpResponse

def index(request,year):
    print(year) # 一个形参代表路径中一个分组的内容,按顺序匹配
    return HttpResponse('菜鸟教程')
正则路径中的有名分组

语法:

(?P<组名>正则表达式)

有名分组按关键字传参,与位置顺序无关。

views 中除了 request,其他形参的数量要与 urls 中的分组数量一致, 并且 views 中的形参名称要与 urls 中的组名对应。

# urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path("^index/(?P[0-9]{4})/(?P[0-9]{2})/$", views.index),
]

# views.py
from django.shortcuts import HttpResponse
def index(request, year, month):
    print(year,month) # 一个形参代表路径中一个分组的内容,按关键字对应匹配
    return HttpResponse('菜鸟教程')

反向解析

随着功能的增加,路由层的 url 发生变化,就需要去更改对应的视图层和模板层的 url,非常麻烦,不便维护。

这时我们可以利用反向解析,当路由层 url 发生改变,在视图层和模板层动态反向解析出更改后的 url,免去修改的操作。

反向解析一般用在模板中的超链接及视图中的重定向。

在 urls.py 中给路由起别名, name=“路由别名” 。

path("login1/", views.login, name="login")

在 views.py 中,从 django.urls 中引入 reverse,利用 reverse(“路由别名”) 反向解析:

return redirect(reverse("login"))

在模板 templates 中的 HTML 文件中,利用 {% url “路由别名” %} 反向解析。


命名空间

命名空间(英语:Namespace)是表示标识符的可见范围。

一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。

一个新的命名空间中可定义任何标识符,它们不会与任何重复的标识符发生冲突,因为重复的定义都处于其它命名空间中。

存在问题: 路由别名 name 没有作用域,Django 在反向解析 URL 时,会在项目全局顺序搜索,当查找到第一个路由别名 name 指定 URL 时,立即返回。当在不同的 app 目录下的urls 中定义相同的路由别名 name 时,可能会导致 URL 反向解析错误。

解决: 使用命名空间。

定义命名空间(include 里面是一个元组)格式如下:

include(("app名称:urls","app名称"))

# 实例

path("app01/", include(("app01.urls","app01"))) 
path("app02/", include(("app02.urls","app02")))

在 views.py 中使用名称空间,语法格式如下:

reverse("app名称:路由别名")

# 实例
return redirect(reverse("app01:login")

在 templates 模板的 HTML 文件中使用名称空间,语法格式如下:

{% url "app名称:路由别名"%}
# 实例

错误处理

当 Django 找不到所匹配的请求 URL 时,或引发了异常时,Django 会调用一个错误处理视图。

这些情况发生时使用的视图通过4个变量指定。它们的默认值应该满足大部分项目,但是通过赋值给它们以进一步的自定义也是可以的。

这些值得在你的根URLconf 中设置。在其它URLconf 中设置这些变量将不会生效果。

它们的值必须是可调用的或者是表示视图的Python 完整导入路径的字符串,可以方便地调用它们来处理错误情况。

这些值是:

handler400 = views.bad_request
handler403 = views.permission_denied
handler404 = views.page_not_found
handler500 = views.page_error
分别在视图定义上述函数返回相应界面即可
当你返回错误,例如 HttpResponseNotFound ,你需要定义错误页面的 HTML 。

return HttpResponseNotFound('Page not found')
为方便起见,在你的网站里有个一致的 404 错误页面是个好办法,Django 提供 Http404 异常。如果你在视图的任何地方引发了 Http404 ,Django 会捕捉到它并且返回标准的错误页面,连同 HTTP 错误代码 404 。

用法示例:

from django.http import Http404
from django.shortcuts import render
from polls.models import Poll

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, 'polls/detail.html', {'poll': p})
为了在 Django 返回404时显示自定义的 HTML,你可以创建名为 404.html 的HTML模板,并将其放置在你的模板树顶层。这个模板将在 DEBUG 设为 False 时提供。

当 DEBUG 为 True 时,你可以提供 Http404 信息,并且在标准的 404 调试模板里显示。使用这些信息来调试;它们通常不适合在生产环境下的404模板。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1023000.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号