Django REST Framework入门指南 – wiki基地


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 之前,你需要:

  1. 熟悉 Python 编程语言: 了解 Python 的基本语法、数据结构、面向对象编程等。
  2. 熟悉 Django 基础知识: 了解 Django 的项目结构、应用程序 (App)、模型 (Models)、视图 (Views)、URL 路由 (URLs)、ORM (Object-Relational Mapper)、迁移 (Migrations) 等核心概念。你至少应该能独立创建一个 Django 项目并定义模型。
  3. 一个可用的开发环境: 安装 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’] # 指定只读字段,序列化时包含,反序列化时忽略
“`

序列化器的工作流程:

  1. 序列化:
    python
    book_instance = Book.objects.get(id=1)
    serializer = BookSerializer(book_instance)
    print(serializer.data) # 输出字典,可转为 JSON
    # {'id': 1, 'title': '...', 'author': '...', ...}
  2. 反序列化与校验:
    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)。它本身不提供任何处理方法(如 getpost)。

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 提供了 SimpleRouterDefaultRouterDefaultRouter 包含了 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 提供了自己的 RequestResponse 对象。

  • rest_framework.request.Request: 封装了 Django 的 HttpRequest 对象,提供了更灵活的数据访问方式,特别是 request.data,它可以自动解析请求体(JSON、表单数据等),而无需手动检查 request.methodrequest.content_type。它还提供了 request.query_params 来方便访问查询字符串参数。
  • rest_framework.response.Response: 接受任何可序列化的 Python 数据作为其第一个参数,并使用 DRF 的渲染器将其渲染成适当的内容类型。你可以方便地通过 status 参数设置 HTTP 状态码。

在 DRF 的视图中,你应该始终使用 DRF 的 RequestResponse 对象。

第三步:构建一个简单的 API 示例

现在,我们来将上述概念结合起来,创建一个简单的 Book API,提供书籍的增删改查功能。

假设你已经创建了一个名为 myproject 的 Django 项目和一个名为 myapi 的应用程序。

  1. 安装 DRF 并添加到 INSTALLED_APPS (已在第二步完成)。
  2. 创建模型 (models.py):
    “`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
    

    运行迁移命令:bash
    python manage.py makemigrations
    python manage.py migrate
    3. **创建序列化器 (`serializers.py`):**python

    myapi/serializers.py

    from rest_framework import serializers
    from .models import Book

    class BookSerializer(serializers.ModelSerializer):
    class Meta:
    model = Book
    fields = [‘id’, ‘title’, ‘author’, ‘published_date’, ‘isbn’]
    # 或者 fields = ‘all
    # read_only_fields = [‘id’] # id 通常是只读的
    4. **创建视图集 (`views.py`):**python

    myapi/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`):**python

    myproject/urls.py

    from django.contrib import admin
    from django.urls import path, include
    from rest_framework.routers import DefaultRouter
    from myapi.views import BookViewSet

    router = 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’, # 启用排序后端
],
# …
}
“`

接着在你的视图中配置:

  1. 使用 django-filter:
    定义一个 FilterSet 类:
    “`python
    # myapi/filters.py

    import django_filters
    from .models import Book

    class BookFilter(django_filters.FilterSet):
    class Meta:
    model = Book
    fields = {
    ‘author’: [‘exact’, ‘icontains’], # 支持精确匹配和模糊匹配 (忽略大小写)
    ‘published_date’: [‘exact’, ‘year__gt’, ‘year__lt’], # 支持日期精确匹配和年份大于/小于
    ‘isbn’: [‘exact’],
    }
    在视图中指定 `filterset_class`:python

    myapi/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
    ``
    现在你可以通过 URL 查询参数进行过滤,例如:
    /api/books/?author=Tolstoy&published_date__year__gt=1900`

  2. 使用 SearchFilterOrderingFilter:
    在视图中指定 search_fieldsordering_fields
    “`python
    # myapi/views.py

    from 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’] # 可选:设置默认排序

    ``
    现在你可以通过 URL 查询参数进行搜索和排序,例如:
    /api/books/?search=Django&ordering=-published_date`

第七步:其他高级功能(简述)

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 (测试): 提供了 APIClientAPITestCase 等工具来方便地测试 API 端点。

这些功能超出了入门指南的范围,但了解它们的存在可以帮助你在未来需要时找到解决方案。

结论

Django REST Framework 是一个构建基于 Django 的 Web API 的强大而灵活的工具包。通过理解并利用其核心概念——序列化器、视图、路由器、认证、权限、分页和过滤——你可以高效地构建出功能齐全、符合 RESTful 规范的 API。

本指南只是一个起点,DRF 还有更多深入的特性和配置选项等待你去探索。最好的学习资源永远是官方文档:https://www.django-rest-framework.org/ (英文) 或其社区翻译。

实践是掌握新技能的关键。尝试在你自己的 Django 项目中构建 API,从小功能开始,逐步增加认证、权限、分页等,你会越来越熟悉 DRF 的强大之处。

祝你在 API 开发之旅中一切顺利!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部