在 Django 中,路由系统的核心是 URLconf,它负责将 URL 请求映射到对应的视图函数或类。每个 URL 请求都会根据设置在 urls.py 文件中的路由规则(即 URLconf)进行匹配。
基本结构
urlpatterns 是一个 URL 模式列表,用于定义 URL 路径与视图(view)之间的映射关系。
每个 URL 路径都映射到一个特定的视图,可以是一个函数视图(function-based view)或者类视图(class-based view)。
路由定义
在 Django 中,我们通过 path() 函数来定义 URL 路由规则。
path() 接受以下几个参数:
第一个参数:URL 路径(字符串类型),比如 ‘hello/’。
第二个参数:视图函数或类视图。as_view() 是用于类视图的。
第三个参数(可选):为这个路由指定一个 名称,通常用于在模板中反向解析 URL。
路由示例
urlpatterns = [
path(‘hello/’, HelloWorldView.as_view(), name=’hello-world’),
]
‘hello/’:这是 URL 路径部分,意味着当用户访问 http://<your-domain>/hello/ 时,Django 会处理这个请求。
HelloWorldView.as_view():HelloWorldView 是一个类视图类(CBV,Class-Based View)。as_view() 是类视图的一个方法,它返回一个可调用的视图实例,供 Django 路由系统使用。也就是说,Django 会调用这个视图类处理请求。
name=’hello-world’:这个是路由的 命名。命名 URL 路径的一个好处是,在模板中或者视图中使用 URL 时,我们可以通过名称来反向生成该 URL,而不需要手动拼接字符串。
路由工作原理
当用户访问 http://<your-domain>/hello/ 时:
- Django 会遍历 urlpatterns 列表,检查每个 path() 中定义的 URL 是否匹配用户请求的 URL。
- 找到匹配的 URL 后,Django 会调用与该 URL 相关联的视图。这里的视图是 HelloWorldView.as_view(),它会创建一个视图实例并处理请求。
- 视图返回一个响应,通常是 HttpResponse 或 JsonResponse,然后 Django 将响应返回给客户端。
函数视图 vs 类视图
Django 提供了两种主要的视图方式:函数视图(FBV)和 类视图(CBV)。
函数视图 (FBV)
# views.py
from django.http import HttpResponse
def hello_world(request):
return HttpResponse(‘Hello, world!’)
# urls.py
urlpatterns = [
path(‘hello/’, hello_world, name=’hello-world’),
]
类视图 (CBV)
# views.py
from django.http import HttpResponse
from django.views import View
class HelloWorldView(View):
def get(self, request):
return HttpResponse(‘Hello, world!’)
# urls.py
urlpatterns = [
path(‘hello/’, HelloWorldView.as_view(), name=’hello-world’),
]
类视图 HelloWorldView
继承了 django.views.View
类。我们在 get()
方法中处理 GET 请求,返回响应。
类视图的优势
- 更清晰的代码结构:类视图将视图的行为按 HTTP 方法(如 get(), post())分开,这样代码更清晰易读。
- 可扩展性强:类视图支持使用 mixins 和 继承 来复用和扩展代码,尤其适合构建复杂的功能。
- 更强的功能支持:如 ListView, DetailView, CreateView, UpdateView 等通用视图类,可以快速实现常见的 CRUD 操作。
更多功能
参数化 URL
你可以在 URL 中定义变量部分,使用 <类型:变量名>
语法。
urlpatterns = [
path(‘book/<int:id>/’, views.book_detail),
]
在视图中,你可以通过 request
对象获取这些参数。
正则表达式
Django 还支持使用正则表达式来匹配 URL,适用于更复杂的场景,通常使用 re_path()
函数。
from django.urls import re_path
urlpatterns = [
re_path(r’^book/(?P<id>\d+)/$’, views.book_detail),
]
Include 子路由
Django 支持将多个 URL 路由分组到不同的模块中,使用 include()
函数可以让你的应用更具模块化。
from django.urls import include, path
urlpatterns = [
path(‘api/’, include(‘app_name.api_urls’)),
]