跳至主要內容

URL调度器

刘春龙原创...大约 5 分钟PythonDjango教程文档

当一个用户请求 Django 站点的一个页面,下面是 Django 系统决定执行哪个 Python 代码使用的算法:

基本介绍

当一个用户请求 Django 站点的一个页面,下面是 Django 系统决定执行哪个 Python 代码使用的算法:

  • Django 确定要使用的根 URLconf 模块,一般是在 settings 中的 ROOT_URLCONF 设置的值,但是如果传入 HttpRequest 对象具有一个 urlconf 属性(由中间件设置),则其值将用于代替 ROOT_URLCONF 设置。
  • Django 加载该 URLconf 模块并查找变量 urlpatterns,它是一个列表 django.urls.path() 和 / 或 django.urls.re_path()实例。
  • Django 按顺序遍历每个 URL 模式,并停在与请求的 URL 匹配的第一个 URL 模式,需要特别注意编写的顺序
  • 一旦某个 URL 模式匹配,Django 就会导入并调用给定的视图,该视图是一个简单的 Python 函数(或基于类的视图方法)。该视图通过以下参数传递:
    • 一个 HttpRequest 实例。
    • 如果匹配的 URL 模式没有返回任何命名组,则来自正则表达式的匹配作为位置参数提供。
    • 关键字参数由路径表达式匹配的任何命名部分组成,并由可选的 kwargs 参数传给 django.urls.path()或 django.urls.re_path()。
  • 如果没有 URL 模式匹配,或者在此过程中的任何点发生异常,Django 将调用适当的错误处理视图

基本使用

  • 修改主应用下的 urls.py 文件
from django.contrib import admin
from django.urls import path

from modules.login.views import (
    loginFunc,
    loginFunc1,
    loginFunc2,
    loginFunc3,
)
from modules.user.views import userFunc

urlpatterns = [
    path("admin/", admin.site.urls),
    path("user/", userFunc),
    path("login/", loginFunc),   # 普通
    path("login/test/", loginFunc1),  # 可以多个斜杠
    path("login/<id>/'", loginFunc2),   # 传递一个名为id的参数
    path("login/str/<int:id>/", loginFunc3),  # 规定传递参数的类型
]



 
 
 
 
 
 





 
 
 
 

  • 业务逻辑的书写
from django.http import HttpResponse

def loginFunc(request):
    return HttpResponse("login")

def loginFunc1(request):
    return HttpResponse("login/test")

def loginFunc2(request, id):
    return HttpResponse("login/" + id)

def loginFunc3(request, id):
    return HttpResponse("login/只能是数字" + str(id))

此时分别访问:

http://localhost:8000/login/open in new window
http://localhost:8000/login/test/open in new window
http://localhost:8000/login/1/open in new window http://localhost:8000/login/a/open in new window

路径转换器

  • str:匹配任何非空字符串,不包括路径分隔符'/'。如果转换器不包含在表达式中,这是默认值。
  • int:匹配零或任何正整数。返回一个 int。
  • slug:匹配由 ASCII 字母或数字组成的字符串,以及横线和下划线字符。例如: building-your-1st-djangosite 可以匹配,django@site 是不可以匹配的。
  • uuid:匹配格式化的 UUID。为防止多个 URL 映射到同一页面,必须包含破折号,并且字母必须是小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID 实例。
  • path:匹配任何非空字符串,包括路径分隔符 '/',可以匹配完整的 URL 路径,而不仅仅是 URL 路径的一部分 str,使用时要谨慎,因为可能造成后续的所有 url 匹配都失效。

自定义转换器

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

  • 一个 regex 类属性,作为一个 re 匹配字符串
  • to_python(self, value)方法,它处理匹配的字符串转换成要传递到视图函数的类型
  • to_url(self, value)方法,用于处理将 Python 类型转换为 URL 中使用的字符串

自定义方式如下:

  1. 在视图同级文件夹下新建一个 converters.py 文件,在文件中定义一个 FourDigitYearConverter 类:

    class FourDigitYearConverter(object):
        regex = '[0-9]{4}'  # 0-9的数字出现4次就能匹配上
    
        def to_python(self, value):
            return int(value)
    
        def to_url(self, value):
            return '%04d'+'哈啊哈' % value
    
  2. 使用 register_converter()方法在 URLconf 中注册自定义转换器类 :

    from django.contrib import admin
    from django.urls import path
    from login import views
    # 注册自定义转换器
    from django.urls import register_converter
    from login.converters import FourDigitYearConverter
    register_converter(FourDigitYearConverter, 'yyyy')  # 随便起个名字
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.loginFunc),   # 普通
        path('login1/<yyyy:id>/', views.loginFunc1),  # 自定义转换器(类型)
    ]
    

此时,我们访问:http://127.0.0.1:8000/login1/1234/open in new windowhttp://127.0.0.1:8000/login1/5478/open in new window

分别看到了 login/1234 和 login/5678

默认值和额外参数

默认值

url 配置

from django.contrib import admin
from django.urls import path

from modules.login.views import (
    loginFunc1,
)

urlpatterns = [
    path("admin/", admin.site.urls),
    path("login/", loginFunc1),
    path("login/<int:page>/", loginFunc1),
]

业务处理

from django.http import HttpResponse

def loginFunc1(request, page=10):
    return HttpResponse(f"返回第{page}页的数据")

此时,分别访问: http://127.0.0.1:8000/login/open in new windowhttp://127.0.0.1:8000/login/22/open in new window

额外参数

url 配置

from django.contrib import admin
from django.urls import path

from modules.login.views import (
    loginFunc1,
)

urlpatterns = [
    path("admin/", admin.site.urls),
    path("login/", loginFunc1, {"name": "lcl"}),
]

业务处理

from django.http import HttpResponse

def loginFunc1(request,name):
    return HttpResponse(f"返回{name}的数据")

此时,访问: http://127.0.0.1:8000/login/open in new window

自定义错误页面

在 settings 中修改配置:

DEBUG = False

ALLOWED_HOSTS = ['*']

在主应用的 urls 中配置:

from django.contrib import admin
from django.urls import path

from modules.login.views import (
    loginFunc1,
)

urlpatterns = [
    path("admin/", admin.site.urls),
    path("login/", loginFunc1),
    # path("login/", loginFunc1, {"name": "lcl"}),
]

handler404 = "modules.login.views.loginFunc2"
handler500 = "modules.login.views.loginFunc3"

错误页面逻辑

from django.http import HttpResponse


def loginFunc1(request, name):
    return HttpResponse(f"返回{name}的数据")


def loginFunc2(request, exception):
    return HttpResponse("404错误页面")


def loginFunc3(request):
    return HttpResponse("500错误页面")

此时,去访问:http://127.0.0.1:8000/login123/open in new window 就会进入 404 错误页面,访问:http://127.0.0.1:8000/login/open in new window 就会进入 500 错误页面

引用其他 URL 调度器

每个子应用下都会拥有自己的 urls.pyopen in new window 文件,合理的方式是在各自的 urls.pyopen in new window 下进行路由配置,之后在主应用下进行导入

  • 子应用的 urls modules.login.urls
from django.urls import path
from modules.login.views import (
    loginFunc1,
    loginFunc2,
    loginFunc3,
)

urlpatterns = [
    path("func1/", loginFunc1, {"name": "lcl"}),
    path("func2/", loginFunc2),
    path("func3/", loginFunc3),
]
  • 主应用的 urls djangostudy.urls
from django.contrib import admin
from django.urls import include, path


urlpatterns = [
    path("admin/", admin.site.urls),
    path("login/", include("modules.login.urls")),
]






 

业务逻辑处理

from django.http import HttpResponse

def loginFunc1(request, name):
    return HttpResponse(f"返回{name}的数据")

def loginFunc2(request):
    return HttpResponse("func2")

def loginFunc3(request):
    return HttpResponse("func3")

此时分别访问:http://127.0.0.1:8000/login/func1/、http://127.0.0.1:8000/login/func2/、http://127.0.0.1:8000/login/func3/open in new window

上次编辑于:
贡献者: 刘春龙
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.7