Django - URL 映射
Django - URL 映射 (URL Mapping)
Section titled “Django - URL 映射 (URL Mapping)”当用户从您的 Django 应用请求一个页面时,Django 需要一种方法来确定哪段 Python 代码(哪个视图/view)应该处理该请求。这个过程由 Django 的 URL 调度器 (URL dispatcher) 管理,通过主要在 urls.py 文件中定义的 URL 模式 (URL patterns) 进行配置。
核心概念:urlpatterns
Section titled “核心概念:urlpatterns”URL 映射的核心是 urlpatterns 列表,它位于您项目的主 urls.py 文件中(例如 myproject/urls.py),也可能位于每个应用的 urls.py 文件中。
Django 处理请求时,会按照顺序检查请求的 URL 路径是否与 urlpatterns 中的每个模式匹配。第一个匹配成功的模式将被使用,Django 会调用关联的视图函数或基于类的视图。
一个典型的项目 urls.py 最初可能看起来像这样:
from django.contrib import adminfrom django.urls import path, include # 导入 include
urlpatterns = [ path('admin/', admin.site.urls), # 在这里添加您的应用的路径 # 示例: path('blog/', include('blog.urls')),]定义 URL 模式:path() 和 re_path()
Section titled “定义 URL 模式:path() 和 re_path()”Django 提供了两个主要函数用于在 urlpatterns 列表中定义 URL 模式:
path(route, view, kwargs=None, name=None):
route:定义 URL 路径模式的字符串。它可以包含尖括号(<>)来捕获 URL 的一部分作为视图的参数。使用简单的路径转换器 (path converters)。view:要调用的视图函数或基于类的视图(.as_view())。kwargs:可选的字典,包含传递给视图的额外关键字参数。name:此 URL 模式的可选名称,用于 URL 反向解析 (URL reversing)(强烈推荐使用)。
re_path(route, view, kwargs=None, name=None):
route:一个包含 Python 正则表达式 的字符串,用于匹配 URL 路径。使用命名组(?P<name>...)来捕获 URL 的一部分。- 其他参数(
view、kwargs、name)与path()相同。
当 path() 的转换器足够时,通常优先使用 path(),因为它更简单易读。re_path() 使用正则表达式提供了更大的能力和灵活性。
示例:基本 URL 映射
Section titled “示例:基本 URL 映射”让我们创建一个简单的应用 myapp,其中包含一个视图,并将一个 URL 映射到它。
from django.http import HttpResponse
def hello_view(request): return HttpResponse("Hello from myapp!")
# myapp/urls.py (创建此文件)from django.urls import pathfrom . import views # 从当前目录导入 views
urlpatterns = [ path('hello/', views.hello_view, name='hello'), # 将 '/hello/' 映射到 hello_view]现在,在主项目的 urls.py 中包含 myapp 的 URL:
from django.contrib import adminfrom django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('myapp/', include('myapp.urls')), # 包含来自 myapp 的 URL]通过此设置,对 /myapp/hello/ 的请求将首先匹配项目 urls.py 中的 'myapp/'。然后 Django 会剥离匹配的部分('myapp/'),并将剩余的字符串('hello/')传递给 myapp/urls.py 进行进一步匹配。在 myapp/urls.py 中,'hello/' 匹配模式,并调用 views.hello_view。
使用 include() 组织 URL
Section titled “使用 include() 组织 URL”如上所示使用 include() 是组织 URL 的标准做法。每个应用在其 urls.py 中管理自己的 URL 命名空间 (URL namespace)。这促进了模块化和可重用性——您只需将其添加到 INSTALLED_APPS 并包含其 URL,就可以将 myapp 应用插入到另一个项目中。
捕获 URL 参数
Section titled “捕获 URL 参数”通常,您需要 URL 的某些部分是动态的,例如产品 ID 或用户名。
使用 path() 和转换器 (Converters):
path() 使用尖括号 <converter:variable_name> 中指定的转换器。
<str:name>:匹配任何非空字符串(不包括 ’/’)。<int:pk>:匹配零或任何正整数。捕获为int类型。<slug:slug>:匹配任何 slug 字符串(ASCII 字母/数字、连字符、下划线)。<uuid:id>:匹配格式化的 UUID。<path:path>:匹配任何非空字符串,包括 ’/‘。用于捕获整个路径非常有用。
def view_article(request, article_id): # article_id 将是一个整数,得益于 <int:> 转换器 text = f"Displaying article Number : {article_id} (Type: {type(article_id).__name__})" return HttpResponse(text)
def view_articles_by_month(request, year, month): # year 和 month 将是整数 text = f"Displaying articles for : {month:02d}/{year}" return HttpResponse(text)
# myapp/urls.pyfrom django.urls import pathfrom . import views
urlpatterns = [ path('article/<int:article_id>/', views.view_article, name='article_detail'), # 示例: /myapp/article/123/ path('articles/<int:year>/<int:month>/', views.view_articles_by_month, name='articles_by_month'), # 示例: /myapp/articles/2024/05/]使用 re_path() 和命名正则表达式组 (Named Regex Groups):
使用标准的 Python 正则表达式和命名组 (?P<variable_name>regex_pattern)。
# (视图通常可以保持与上面相同)
# myapp/urls.pyfrom django.urls import re_pathfrom . import views
urlpatterns = [ re_path(r'^article/(?P<article_id>\d+)/$', views.view_article, name='article_detail'), # 示例: /myapp/article/123/ # \d+ 匹配一个或多个数字
re_path(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.view_articles_by_month, name='articles_by_month'), # 示例: /myapp/articles/2024/05/ # \d{4} 精确匹配 4 个数字,\d{2} 精确匹配 2 个数字]从 path() 和 re_path() 捕获的值都作为关键字参数传递给视图函数(匹配尖括号中的变量名或正则表达式组名)。
URL 名称和反向解析 (Reversing)
Section titled “URL 名称和反向解析 (Reversing)”为您的 URL 模式分配一个 name(例如 name='article_detail')允许您在代码的其他部分(视图、模板、模型)中使用 reverse() 函数或 {% url %} 模板标签明确引用它们。这对于可维护性至关重要,因为您可以更改 urls.py 中实际的 URL 路径结构,而不会破坏其他地方的引用。
进一步阅读:
- Django URL 调度器文档:https://docs.djangoproject.com/en/stable/topics/http/urls/
- Django
path()和re_path()参考:https://docs.djangoproject.com/en/stable/ref/urls/