Django REST Framework 入门指南:构建强大、灵活的 Web API
引言:为何需要 Web API 以及 DRF 的作用
在当今互联网应用中,Web API (Application Programming Interface) 扮演着至关重要的角色。它们是不同软件系统之间互相通信的桥梁,使得前端应用(如 Web 浏览器、移动 App)、第三方服务甚至其他后端服务能够方便地获取或操作数据。RESTful API 作为一种流行的 API 设计风格,以其无状态、资源导向的特性赢得了广泛应用。
Django 是一个功能强大、高效的 Python Web 框架。它以“约定优于配置”和“不要重复自己 (DRY)”的原则著称,提供了构建 Web 应用所需的几乎所有组件:ORM、URL 路由器、模板系统、表单处理、管理后台等。然而,Django 原生设计主要面向服务端渲染的传统 Web 应用,虽然可以处理 JSON 响应,但构建一个完整的、符合 RESTful 标准的 API 则需要更多额外的工作,比如:
- 数据序列化 (Serialization): 将复杂的 Python 对象(如 Django 模型实例、查询集)转换为易于在网络上传输的格式(如 JSON、XML),反之亦然(反序列化,用于处理客户端发送的数据)。
- 请求解析 (Request Parsing): 处理不同内容类型的请求体(JSON、表单数据等)。
- 视图处理 (View Handling): 定义处理各种 HTTP 方法 (GET, POST, PUT, DELETE) 的逻辑。
- 认证 (Authentication): 确定是谁发出的请求。
- 权限 (Permissions): 确定请求者是否有权执行特定操作。
- 限流 (Throttling): 控制请求速率以防止滥用。
- 分页 (Pagination): 处理大量数据,避免一次性返回过多内容。
- 过滤和搜索 (Filtering & Searching): 允许客户端根据特定条件查询数据。
- API 文档 (API Documentation): 自动生成或方便编写 API 文档。
手动实现这些功能既耗时又容易出错。这就是 Django REST Framework (DRF) 诞生的原因。
Django REST Framework 是一个灵活且功能强大的工具包,用于构建基于 Django 的 Web API。它建立在 Django 的基础上,提供了构建 RESTful API 所需的几乎所有抽象和工具,极大地简化了 API 的开发过程。DRF 提供了:
- 强大的 Serializer 类,用于轻松地序列化和反序列化数据。
- 基于类的 Views,可以处理不同的 HTTP 方法,并集成了认证、权限、限流等功能。
- 灵活的认证和权限策略。
- 可定制的 Pagination、Filtering 和 Searching 后端。
- 可浏览的 API (Browsable API),方便开发者测试和调试。
- 丰富的文档和活跃的社区支持。
本指南将带你一步步进入 DRF 的世界,从安装到核心概念,再到构建一个简单的 API 示例。
前置准备
在开始学习 DRF 之前,你需要:
- 熟悉 Python 编程语言: 了解 Python 的基本语法、数据结构、面向对象编程等。
- 熟悉 Django 基础知识: 了解 Django 的项目结构、应用程序 (App)、模型 (Models)、视图 (Views)、URL 路由 (URLs)、ORM (Object-Relational Mapper)、迁移 (Migrations) 等核心概念。你至少应该能独立创建一个 Django 项目并定义模型。
- 一个可用的开发环境: 安装 Python、pip,建议使用虚拟环境。
假设你已经具备上述基础,我们将直接进入 DRF 的安装与配置。
第一步:安装和配置 DRF
首先,确保你的 Django 项目已经创建并处于虚拟环境中。
使用 pip 安装 Django REST Framework:
bash
pip install djangorestframework
安装完成后,将 rest_framework
添加到你的 Django 项目的 settings.py
文件中的 INSTALLED_APPS
列表里:
“`python
settings.py
INSTALLED_APPS = [
# … 其他已安装的应用程序
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
# 添加 DRF
'rest_framework',
# 你的应用程序 (例如: 'myapi')
'myapi',
]
… 其他设置
“`
将 'rest_framework'
添加到 INSTALLED_APPS
会注册 DRF 的内置视图、序列化器、请求/响应对象等,并启用其功能。
第二步:核心概念解析
DRF 的强大在于其提供了一系列抽象,帮助我们以结构化的方式构建 API。理解这些核心概念是掌握 DRF 的关键。
2.1 Serializers (序列化器)
序列化是 DRF 中最基础且最重要的概念之一。它的核心作用是将复杂的对象(如 Django 模型实例、查询集、自定义 Python 对象)序列化成易于传输的标准格式(如 JSON、XML),以及将接收到的标准格式数据反序列化回复杂的对象,同时进行数据校验。
想象一下,你的 Django 模型是 Python 对象,数据库里存的是结构化数据。当客户端请求数据时,你需要把这些 Python 对象或数据库记录转换成 JSON 字符串发送出去;当客户端发送 JSON 数据创建或更新资源时,你需要把 JSON 字符串转换成 Python 对象或数据库记录来处理。Serializers 就是做这个转换和校验工作的。
DRF 提供了 rest_framework.serializers.Serializer
基类。通常,我们更常使用 rest_framework.serializers.ModelSerializer
,它会自动根据 Django 模型生成一系列字段,极大地简化了序列化器的定义。
示例:
假设你有一个简单的 Django 模型:
“`python
myapi/models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
isbn = models.CharField(max_length=13, unique=True)
def __str__(self):
return self.title
“`
使用 ModelSerializer
定义一个对应的序列化器:
“`python
myapi/serializers.py
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
# fields = ‘all‘ # 包含模型所有字段
fields = [‘id’, ‘title’, ‘author’, ‘published_date’, ‘isbn’] # 指定需要包含的字段
# exclude = [‘isbn’] # 排除某些字段
# read_only_fields = [‘isbn’] # 指定只读字段,序列化时包含,反序列化时忽略
“`
序列化器的工作流程:
- 序列化:
python
book_instance = Book.objects.get(id=1)
serializer = BookSerializer(book_instance)
print(serializer.data) # 输出字典,可转为 JSON
# {'id': 1, 'title': '...', 'author': '...', ...} - 反序列化与校验:
python
data = {'title': 'New Book', 'author': 'New Author', 'published_date': '2023-01-01', 'isbn': '1234567890123'}
serializer = BookSerializer(data=data)
if serializer.is_valid(): # 校验数据
book_instance = serializer.save() # 创建或更新模型实例
print("数据有效,已保存:", book_instance)
else:
print("数据无效:", serializer.errors) # 输出校验错误信息
序列化器还支持定义自定义字段、处理嵌套关系、进行字段级和对象级验证等高级功能。
2.2 Views (视图)
在 Django 中,视图函数或类负责接收 Web 请求并返回响应。DRF 提供了自己的视图类,它们是 Django 视图的超集,增加了许多专为 API 设计的功能。
2.2.1 APIView
rest_framework.views.APIView
是 DRF 视图的基础类。它与 Django 的 View
类类似,但提供了以下增强:
- 使用 DRF 的
Request
对象,该对象扩展了 Django 的HttpRequest
,增加了更灵活的请求数据解析(request.data
)。 - 使用 DRF 的
Response
对象,该对象接收原生 Python 数据(字典、列表等),并处理内容协商,将其渲染成客户端期望的格式(默认为 JSON),同时允许方便地设置状态码。 - 自动应用认证、权限和限流策略。
APIView
通常用于处理那些不直接映射到模型实例的 API 端点,或者当你需要完全自定义请求处理逻辑时。
示例:
“`python
myapi/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class HelloWorldAPIView(APIView):
def get(self, request, format=None):
“””
处理 GET 请求
“””
return Response({“message”: “Hello, World!”}, status=status.HTTP_200_OK)
def post(self, request, format=None):
"""
处理 POST 请求
request.data 包含解析后的请求体数据
"""
data = request.data
message = data.get("message", "No message received")
return Response({"received": message}, status=status.HTTP_201_CREATED)
“`
2.2.2 GenericAPIView 与 Mixins
rest_framework.generics.GenericAPIView
继承自 APIView
,它提供了一些核心功能,例如确定使用的序列化器 (serializer_class
) 和查询集 (queryset
),以及一些用于获取特定对象的方法 (get_object
)。它本身不提供任何处理方法(如 get
或 post
)。
GenericAPIView
通常与Mixin 类一起使用。Mixin 类提供具体的行为实现,例如列出查询集(ListModelMixin
)、创建模型实例(CreateModelMixin
)、检索单个模型实例(RetrieveModelMixin
)、更新(UpdateModelMixin
)、删除(DestroyModelMixin
)等。
通过继承 GenericAPIView
和一个或多个 Mixin,我们可以快速构建符合常见模式的 API 视图。
示例:
构建一个列出所有书籍和创建新书籍的 API 端点:
“`python
myapi/views.py
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer
class BookListCreateAPIView(generics.ListCreateAPIView):
# GenericAPIView 的配置项
queryset = Book.objects.all()
serializer_class = BookSerializer
# ListModelMixin 提供 .list() 方法 (对应 GET 请求)
# CreateModelMixin 提供 .create() 方法 (对应 POST 请求)
# ListCreateAPIView 结合了 ListModelMixin 和 CreateModelMixin
# 并继承 GenericAPIView,自动映射 GET/POST 到 list/create 方法
“`
构建一个检索、更新和删除单个书籍的 API 端点:
“`python
myapi/views.py
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer
class BookRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# RetrieveModelMixin 提供 .retrieve() (GET)
# UpdateModelMixin 提供 .update() (PUT/PATCH)
# DestroyModelMixin 提供 .destroy() (DELETE)
# RetrieveUpdateDestroyAPIView 结合了这三个 Mixin 并继承 GenericAPIView
# 自动映射 GET/PUT/PATCH/DELETE 到相应方法
# 它还需要从 URL 中捕获主键或 slug 来获取特定对象,通常使用 <pk> 或 <slug>
“`
使用 GenericAPIView
和 Mixins 是一种快速构建标准 RESTful API 端点的方式。
2.2.3 ViewSets (视图集)
rest_framework.viewsets.ViewSet
及其子类(如 ModelViewSet
)将一组相关的视图逻辑组织在一起,例如对应于同一个模型的 CRUD (Create, Retrieve, Update, Delete) 操作。
ViewSet 不提供像 get()
、post()
这样的方法,而是提供如 list()
、retrieve()
、create()
、update()
、partial_update()
、destroy()
等方法,这些方法对应于常见的 RESTful 操作。
ModelViewSet
是最常用的 ViewSet,它继承了 GenericViewSet
并混合了所有标准的 Mixin 类 (ListModelMixin
, RetrieveModelMixin
, CreateModelMixin
, UpdateModelMixin
, DestroyModelMixin
),可以直接用于提供一个模型的完整 CRUD API。
示例:
使用 ModelViewSet
为 Book 模型构建完整的 CRUD API:
“`python
myapi/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
class BookViewSet(viewsets.ModelViewSet):
“””
提供 Book 的 CRUD 操作的 API endpoint
“””
queryset = Book.objects.all()
serializer_class = BookSerializer
# ModelViewSet 提供了 list, retrieve, create, update, partial_update, destroy 方法
# 通过路由器可以自动生成对应的 URL 模式
“`
ViewSets 本身不能直接处理请求,需要通过路由器 (Routers) 来将请求方法 (GET, POST 等) 映射到 ViewSet 的具体方法 (list, create 等),并生成对应的 URL 模式。
2.3 Routers (路由器)
使用 ViewSet
的一个主要好处是可以使用 DRF 提供的路由器来自动生成 URL 配置。这避免了为 ViewSet 的每个操作手动编写 urlpattern
。
DRF 提供了 SimpleRouter
和 DefaultRouter
。DefaultRouter
包含了 SimpleRouter
的功能,并额外提供了根视图(包含所有 ViewSet 的超链接)和 .json
后缀的支持。通常推荐使用 DefaultRouter
。
示例:
“`python
myproject/urls.py (项目主 URL 文件)
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from myapi.views import BookViewSet # 导入你的 ViewSet
创建一个路由器实例
router = DefaultRouter()
注册你的 ViewSet 到路由器
第一个参数是 URL 前缀 (例如: ‘books’)
第二个参数是 ViewSet 类
第三个参数是可选的 base_name,用于生成 URL 名称,如果 queryset 属性有定义,通常可以省略
router.register(r’books’, BookViewSet)
urlpatterns = [
path(‘admin/’, admin.site.urls),
# 将路由器生成的 URL 模式包含到项目的主 URL 配置中
path(‘api/’, include(router.urls)), # 例如访问 /api/books/
# path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)), # 可选,用于Browsable API的登录/注销
]
“`
上面的配置会自动为 BookViewSet
生成以下 URL 模式(大致):
/api/books/
(GET): 对应BookViewSet.list()
/api/books/
(POST): 对应BookViewSet.create()
/api/books/{pk}/
(GET): 对应BookViewSet.retrieve()
/api/books/{pk}/
(PUT): 对应BookViewSet.update()
/api/books/{pk}/
(PATCH): 对应BookViewSet.partial_update()
/api/books/{pk}/
(DELETE): 对应BookViewSet.destroy()
使用 ViewSets 和 Routers 是构建 RESTful API 的高效方式,它们遵循了 DRY 原则。
2.4 Request 和 Response 对象
正如前面提到的,DRF 提供了自己的 Request
和 Response
对象。
rest_framework.request.Request
: 封装了 Django 的HttpRequest
对象,提供了更灵活的数据访问方式,特别是request.data
,它可以自动解析请求体(JSON、表单数据等),而无需手动检查request.method
和request.content_type
。它还提供了request.query_params
来方便访问查询字符串参数。rest_framework.response.Response
: 接受任何可序列化的 Python 数据作为其第一个参数,并使用 DRF 的渲染器将其渲染成适当的内容类型。你可以方便地通过status
参数设置 HTTP 状态码。
在 DRF 的视图中,你应该始终使用 DRF 的 Request
和 Response
对象。
第三步:构建一个简单的 API 示例
现在,我们来将上述概念结合起来,创建一个简单的 Book API,提供书籍的增删改查功能。
假设你已经创建了一个名为 myproject
的 Django 项目和一个名为 myapi
的应用程序。
- 安装 DRF 并添加到
INSTALLED_APPS
(已在第二步完成)。 -
创建模型 (
models.py
):
“`python
# myapi/models.pyfrom django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
isbn = models.CharField(max_length=13, unique=True)def __str__(self): return self.title
运行迁移命令:
bash
python manage.py makemigrations
python manage.py migrate
3. **创建序列化器 (`serializers.py`):**
pythonmyapi/serializers.py
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = [‘id’, ‘title’, ‘author’, ‘published_date’, ‘isbn’]
# 或者 fields = ‘all‘
# read_only_fields = [‘id’] # id 通常是只读的
4. **创建视图集 (`views.py`):**
pythonmyapi/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer导入权限类,后面会讲到
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser, AllowAny
class BookViewSet(viewsets.ModelViewSet):
“””
提供 Book 的 CRUD 操作的 API endpoint
“””
queryset = Book.objects.all().order_by(‘title’) # 可以指定默认排序
serializer_class = BookSerializer
# permission_classes = [AllowAny] # 暂时允许所有人访问# 可以按需覆盖 ViewSet 的方法 # def list(self, request, *args, **kwargs): # # 自定义列表行为 # return super().list(request, *args, **kwargs) # 可以添加自定义 action (需要路由器的支持) # from rest_framework.decorators import action # from rest_framework.response import Response # @action(detail=True, methods=['post']) # def publish(self, request, pk=None): # book = self.get_object() # # 执行发布逻辑 # return Response({'status': 'book published'})
5. **配置 URL 路由 (`urls.py`):**
pythonmyproject/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from myapi.views import BookViewSetrouter = DefaultRouter()
router.register(r’books’, BookViewSet) # 注册 BookViewSet,URL 前缀为 ‘books’urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(router.urls)), # 包含 DRF 路由器生成的 URL
# 可选:用于Browsable API 的登录/注销链接
path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)),
]
6. **运行开发服务器:**
bash
python manage.py runserver
“`
7. 测试 API:打开浏览器,访问
http://127.0.0.1:8000/api/
。如果你包含了api-auth
的 URL,并且使用的是DefaultRouter
,你应该能看到一个漂亮的Browsable API 根页面,列出了/books/
终结点的链接。点击
/books/
链接,你将看到 Book 列表页面(如果数据库中有书的话),或者一个创建新书的表单。这就是 DRF 提供的 Browsable API 功能,它根据你的视图和序列化器自动生成 HTML 界面,方便进行 GET 和 POST 请求测试。你也可以使用 Postman、curl 或其他 HTTP 客户端来测试:
- GET /api/books/: 获取所有书籍列表。
- POST /api/books/: 创建一本新书 (发送 JSON 数据)。
- GET /api/books/1/: 获取 ID 为 1 的书籍详情。
- PUT /api/books/1/: 更新 ID 为 1 的书籍 (发送 JSON 数据)。
- PATCH /api/books/1/: 部分更新 ID 为 1 的书籍 (发送 JSON 数据)。
- DELETE /api/books/1/: 删除 ID 为 1 的书籍。
恭喜!你已经成功构建了一个功能齐全的 RESTful API。
第四步:API 的安全与控制
构建好 API 后,通常需要考虑谁能访问以及他们能做什么。DRF 提供了灵活的认证和权限机制。
4.1 Authentication (认证)
认证用于识别发出请求的客户端是谁。DRF 不强制使用某种特定的认证方式,而是提供了一个可插拔的系统。常见的认证方式包括:
rest_framework.authentication.SessionAuthentication
: 使用 Django 的会话框架认证,适用于与浏览器交互(依赖 Cookie)。Browsable API 默认使用此认证。rest_framework.authentication.BasicAuthentication
: 使用 HTTP Basic 认证(Base64 编码的用户名和密码)。rest_framework.authentication.TokenAuthentication
: 基于简单的 Token 认证,适用于移动 App 或第三方服务。客户端在请求头中发送一个 Token (Authorization: Token <token>
)。rest_framework_simplejwt
: 一个流行的第三方库,提供基于 JSON Web Token (JWT) 的认证。
你可以在 settings.py
中设置默认认证类:
“`python
settings.py
REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.SessionAuthentication’,
‘rest_framework.authentication.TokenAuthentication’,
# ‘rest_framework_simplejwt.authentication.JWTAuthentication’, # 如果安装并配置了 django-rest-framework-simplejwt
]
}
“`
或者在视图类上通过 authentication_classes
属性指定:
“`python
myapi/views.py
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
class RestrictedBookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = [IsAuthenticated] # 要求已认证
authentication_classes = [TokenAuthentication] # 只使用 Token 认证
“`
4.2 Permissions (权限)
权限用于决定已认证的客户端是否有权执行特定操作。权限类通常在认证之后运行。DRF 提供了多种权限类:
rest_framework.permissions.AllowAny
: 允许任何用户访问(默认)。rest_framework.permissions.IsAuthenticated
: 只允许已认证用户访问。rest_framework.permissions.IsAdminUser
: 只允许管理员用户访问。rest_framework.permissions.IsAuthenticatedOrReadOnly
: 已认证用户可以完全访问,未认证用户只能进行读操作 (GET, HEAD, OPTIONS)。rest_framework.permissions.DjangoModelPermissions
: 使用 Django 的标准django.contrib.auth
模型权限。rest_framework.permissions.DjangoObjectPermissions
: 支持对象级别的 Django 权限(需要配合第三方库如django-guardian
)。
同样,你可以在 settings.py
中设置默认权限类:
“`python
settings.py
REST_FRAMEWORK = {
# … 其他设置
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticatedOrReadOnly’ # 默认只读
]
}
“`
或者在视图类上通过 permission_classes
属性指定:
“`python
myapi/views.py
from rest_framework.permissions import IsAdminUser
class AdminOnlyBookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = [IsAdminUser] # 只允许管理员用户访问
“`
你也可以创建自定义权限类,通过继承 rest_framework.permissions.BasePermission
并实现 has_permission(self, request, view)
(检查是否有权访问视图本身) 或 has_object_permission(self, request, view, obj)
(检查是否有权访问特定对象) 方法。
示例:自定义权限类 (只允许作者修改自己的书):
“`python
myapi/permissions.py
from rest_framework import permissions
class IsAuthorOrReadOnly(permissions.BasePermission):
“””
自定义权限,只允许作者编辑,其他用户只读。
“””
def has_object_permission(self, request, view, obj):
# 读取权限总是允许,无论请求方法是什么
if request.method in permissions.SAFE_METHODS:
return True
# 写权限只允许对象 (Book) 的作者
# 假设你的 Book 模型有一个指向 User 的外键 'author'
# 如果你的模型作者字段不是 'author',需要相应修改
return obj.author == request.user
“`
然后在视图中使用:
“`python
myapi/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
from .permissions import IsAuthorOrReadOnly # 导入自定义权限
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all().order_by(‘title’)
serializer_class = BookSerializer
# 使用自定义权限
# IsAuthenticatedOrReadOnly 先检查是否已认证或只读,
# IsAuthorOrReadOnly 在已认证且非只读的情况下检查是否是作者
permission_classes = [IsAuthenticatedOrReadOnly, IsAuthorOrReadOnly]
“`
第五步:处理大量数据:分页 (Pagination)
当数据集很大时,一次性返回所有数据会消耗大量资源并影响性能。分页可以将大型结果集分割成较小的块,分批返回给客户端。
DRF 提供了几种内置分页类:
rest_framework.pagination.PageNumberPagination
: 基于页码的分页。客户端通过 URL 参数?page=3&page_size=100
请求数据。rest_framework.pagination.LimitOffsetPagination
: 基于偏移量和限制数量的分页。客户端通过?limit=100&offset=200
请求数据。rest_framework.pagination.CursorPagination
: 基于游标的分页,适用于大型、经常变化的数据集,并且能保证结果的一致性,但不支持负向排序或精确计算总页数。
你可以通过 settings.py
设置全局默认分页类:
“`python
settings.py
REST_FRAMEWORK = {
# … 其他设置
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10 # 默认每页条数
}
“`
或者在视图类上通过 pagination_class
属性指定:
“`python
myapi/views.py
from rest_framework.pagination import LimitOffsetPagination
class BookListView(generics.ListAPIView): # 或者 ViewSet 的 list 方法
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = LimitOffsetPagination # 对此视图使用 Limit/Offset 分页
# 可以进一步定制分页类,例如设置最大页数或默认限制
# class CustomPageNumberPagination(PageNumberPagination):
# page_size_query_param = 'size' # 客户端参数改为 size
# max_page_size = 100
# page_size = 20
# pagination_class = CustomPageNumberPagination
“`
在 Browsable API 中,启用了分页的列表视图会自动显示分页控件。
第六步:查询数据:过滤和搜索 (Filtering & Searching)
API 客户端通常需要根据特定条件过滤或搜索数据。DRF 通过 Filter Backends 提供了实现这些功能的机制。
DRF 内置了简单的过滤和搜索后端:
rest_framework.filters.SearchFilter
: 基于搜索关键字对某些字段进行模糊匹配 (?search=keyword
)。rest_framework.filters.OrderingFilter
: 允许客户端指定结果排序字段 (?ordering=author,-published_date
)。
更强大的过滤功能通常使用第三方库 django-filter
,它与 DRF 集成良好。
首先,安装 django-filter
:
bash
pip install django-filter
然后在 settings.py
中添加到 INSTALLED_APPS
并配置 DRF 默认过滤器后端:
“`python
settings.py
INSTALLED_APPS = [
# … 其他应用
‘django_filters’, # 添加 django-filter
‘rest_framework’,
# …
]
REST_FRAMEWORK = {
# … 其他设置
‘DEFAULT_FILTER_BACKENDS’: [
‘django_filters.rest_framework.DjangoFilterBackend’, # 启用 django-filter 后端
‘rest_framework.filters.SearchFilter’, # 启用搜索后端
‘rest_framework.filters.OrderingFilter’, # 启用排序后端
],
# …
}
“`
接着在你的视图中配置:
-
使用
django-filter
:
定义一个 FilterSet 类:
“`python
# myapi/filters.pyimport django_filters
from .models import Bookclass BookFilter(django_filters.FilterSet):
class Meta:
model = Book
fields = {
‘author’: [‘exact’, ‘icontains’], # 支持精确匹配和模糊匹配 (忽略大小写)
‘published_date’: [‘exact’, ‘year__gt’, ‘year__lt’], # 支持日期精确匹配和年份大于/小于
‘isbn’: [‘exact’],
}
在视图中指定 `filterset_class`:
pythonmyapi/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
from .filters import BookFilter # 导入 FilterSet 类class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# filter_backends = [DjangoFilterBackend] # 如果设置了全局默认,这里可以省略
filterset_class = BookFilter # 指定使用的 FilterSet
``
/api/books/?author=Tolstoy&published_date__year__gt=1900`
现在你可以通过 URL 查询参数进行过滤,例如: -
使用
SearchFilter
和OrderingFilter
:
在视图中指定search_fields
和ordering_fields
:
“`python
# myapi/views.pyfrom rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
from rest_framework import filters # 导入内置过滤器class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# filter_backends = [filters.SearchFilter, filters.OrderingFilter] # 如果设置了全局默认,这里可以省略
search_fields = [‘title’, ‘author’, ‘isbn’] # 可搜索的字段列表
ordering_fields = [‘title’, ‘author’, ‘published_date’] # 可排序的字段列表
# ordering = [‘title’] # 可选:设置默认排序``
/api/books/?search=Django&ordering=-published_date`
现在你可以通过 URL 查询参数进行搜索和排序,例如:
第七步:其他高级功能(简述)
DRF 还提供了许多其他功能来帮助你构建更健壮和灵活的 API:
- Versioning (版本控制): 支持在 URL、Header 或 Query Parameter 中指定 API 版本,以便在 API 演进时保持向后兼容性。
- Throttling (限流): 控制客户端或用户在一定时间内可以发出的请求数量,防止 API 被滥用。
- Parsers (解析器): 处理不同类型的请求体(如 JSON, XML, Form Data)。DRF 默认支持 JSON 和 Form Data。
- Renderers (渲染器): 将序列化后的数据渲染成客户端期望的格式(如 JSON, HTML)。Browsable API 使用 HTML 渲染器。
- Custom Fields (自定义字段): 创建自定义序列化器字段来处理复杂的数据表示。
- Testing (测试): 提供了
APIClient
和APITestCase
等工具来方便地测试 API 端点。
这些功能超出了入门指南的范围,但了解它们的存在可以帮助你在未来需要时找到解决方案。
结论
Django REST Framework 是一个构建基于 Django 的 Web API 的强大而灵活的工具包。通过理解并利用其核心概念——序列化器、视图、路由器、认证、权限、分页和过滤——你可以高效地构建出功能齐全、符合 RESTful 规范的 API。
本指南只是一个起点,DRF 还有更多深入的特性和配置选项等待你去探索。最好的学习资源永远是官方文档:https://www.django-rest-framework.org/ (英文) 或其社区翻译。
实践是掌握新技能的关键。尝试在你自己的 Django 项目中构建 API,从小功能开始,逐步增加认证、权限、分页等,你会越来越熟悉 DRF 的强大之处。
祝你在 API 开发之旅中一切顺利!