Django REST Framework 入门指南 – wiki基地


Django REST Framework 入门指南:构建强大的 Web API

欢迎来到 Django REST Framework (DRF) 的世界!如果你是一名 Django 开发者,渴望构建一个强大、灵活且易于维护的 Web API,那么 DRF 无疑是你最得力的助手。它基于 Django 的强大基础之上,提供了一系列工具,极大地简化了构建 RESTful API 的过程。

本指南将带你从零开始,逐步深入 DRF 的核心概念,包括序列化器(Serializers)、视图(Views)、URL 路由(URLs)、身份认证(Authentication)、权限(Permissions)等,最终帮助你使用 DRF 搭建起一个功能完备的基础 API。

为什么选择 Django REST Framework?

在深入学习之前,我们先来了解一下 DRF 为什么如此受欢迎:

  1. 基于 Django 的强大生态: 如果你熟悉 Django,你会发现 DRF 的结构和设计理念与 Django 高度一致,学习曲线平缓。你可以直接利用 Django 已有的 Model、ORM、Settings 等功能。
  2. 序列化器 (Serializers): 轻松处理复杂数据的序列化(将数据库对象转换为 JSON/XML 等格式)和反序列化(将接收到的 JSON/XML 数据转换为 Python 对象并进行验证)。这是构建 API 的核心需求。
  3. 可浏览的 API (Browsable API): DRF 提供了一个非常友好的 Web 界面,允许你在浏览器中直接与 API 交互,测试端点,查看输入/输出,这极大地提高了开发效率和调试便利性。
  4. 丰富的视图类 (Views): 提供了通用的视图类(Generic Views)和视图集(ViewSets),可以快速实现常见的 CRUD (Create, Retrieve, Update, Delete) 操作,避免编写大量重复代码。
  5. 灵活的认证和权限系统 (Authentication & Permissions): 内置支持多种认证方案(如 Session、Token、JWT)和权限控制,可以轻松地保护你的 API。
  6. 强大的功能扩展: 内置了分页 (Pagination)、过滤 (Filtering)、搜索 (Search)、限流 (Throttling)、版本控制 (Versioning) 等常用 API 功能。
  7. 广泛的社区支持: 作为一个流行框架,DRF 拥有庞大的社区,遇到问题很容易找到解决方案和资源。

总之,DRF 提供了构建 Web API 所需的几乎所有工具,让你能够专注于业务逻辑而非底层实现细节。

前提条件

在开始本指南之前,你需要:

  • 对 Python 语言有基本了解。
  • 已经安装了 Python 和 pip。
  • 对 Django 框架有基本认识,包括如何创建项目和应用、定义 Models、运行迁移等。

环境搭建和项目初始化

首先,我们需要创建一个 Django 项目并安装 DRF。

  1. 创建虚拟环境(推荐):

    “`bash
    python -m venv venv
    source venv/bin/activate # macOS/Linux

    venv\Scripts\activate # Windows

    “`

  2. 安装 Django 和 Django REST Framework:

    bash
    pip install django djangorestframework

  3. 创建 Django 项目:

    bash
    django-admin startproject myapi_project .

    注意 . 表示在当前目录下创建项目,方便管理。

  4. 创建 Django 应用:

    我们创建一个名为 products 的应用来管理商品数据。

    bash
    python manage.py startapp products

  5. 注册应用和 DRF:

    打开 myapi_project/settings.py 文件,在 INSTALLED_APPS 列表中添加 'rest_framework''products'

    “`python

    myapi_project/settings.py

    INSTALLED_APPS = [
    ‘django.contrib.admin’,
    ‘django.contrib.auth’,
    ‘django.contrib.contenttypes’,
    ‘django.contrib.sessions’,
    ‘django.contrib.messages’,
    ‘django.contrib.staticfiles’,
    # Third-party apps
    ‘rest_framework’, # <– 添加 DRF

    # Local apps
    'products',     # <-- 添加你的应用
    

    ]

    … 其他配置保持不变

    “`

至此,我们的环境已经搭建完毕,DRF 也已经成功集成到 Django 项目中。

第一步:定义 Model

为了演示,我们在 products 应用中定义一个简单的 Product Model。

打开 products/models.py 文件:

“`python

products/models.py

from django.db import models

class Product(models.Model):
name = models.CharField(max_length=100, unique=True)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self):
    return self.name

“`

定义好 Model 后,别忘了进行数据库迁移:

bash
python manage.py makemigrations
python manage.py migrate

现在,我们的数据库中就有了 Product 表。你可以通过 Django Admin 添加一些示例数据方便后续测试。

第二步:创建 Serializer

Serializer 是 DRF 中一个非常核心的概念。它的主要作用有两个:

  1. 序列化 (Serialization): 将复杂的 Python 数据类型(如 Django Model 实例或 QuerySet)转换为易于通过网络传输的格式(如 JSON)。
  2. 反序列化 (Deserialization): 将接收到的低级数据(如 JSON 格式的请求体)解析并转换为 Python 对象,并对数据的有效性进行验证。

对于 Django Model,DRF 提供了 ModelSerializer 类,可以自动为你生成基于 Model 字段的 Serializer,极大地简化了代码。

products 应用目录下创建一个 serializers.py 文件:

“`python

products/serializers.py

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ‘all‘ # 表示序列化 Model 中的所有字段
# 或者你可以明确指定需要序列化的字段:
# fields = [‘id’, ‘name’, ‘description’, ‘price’, ‘stock’]
# 或者排除某些字段:
# exclude = [‘created_at’, ‘updated_at’]
“`

这里,我们创建了一个 ProductSerializer,它继承自 serializers.ModelSerializer。在内部的 Meta 类中,我们指定了要关联的 Model (Product) 和需要序列化的字段 (__all__ 表示所有字段)。

这个 Serializer 现在可以:

  • 接收一个 Product 实例或 QuerySet,并将其转换为字典,然后 DRF 会将其渲染成 JSON。
  • 接收一个字典(通常来自请求体),验证其字段是否与 Product Model 匹配,如果有效,可以用来创建或更新 Product 实例。

第三步:创建 View

在 Django 中,View 负责接收 HTTP 请求并返回 HTTP 响应。DRF 的 View 同样如此,但它提供了更适合处理 API 请求/响应的类。

DRF 提供了多种 View 的实现方式:

  1. APIView DRF 提供的基础 View 类,是 Django View 类的增强版。它处理 DRF 的 RequestResponse 对象,并提供认证、权限、限流等功能。你需要自己实现各种 HTTP 方法(get, post, put, delete 等)。
  2. 通用视图类 (Generic Views): 基于 APIView,提供了一系列 Mixins (混入类),用于实现常见的操作(如 ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin)。你可以组合这些 Mixins 来快速构建 View。
  3. 视图集 (ViewSets): 更高层次的抽象。ViewSet 不提供像 get, post 这样的方法,而是提供像 list, create, retrieve, update, partial_update, destroy 这样的操作。ViewSets 通常与 Router 配合使用,可以自动生成 URL 模式。这使得为一组相关的视图编写代码变得非常高效。

对于常见的 Model CRUD 操作,ModelViewSet 是最常用的选择,因为它集成了所有必要的 Mixins 和 GenericAPIView 的功能。我们将使用 ModelViewSet 来创建 Product 的 API 视图。

打开 products/views.py 文件:

“`python

products/views.py

from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
“””
API endpoint that allows products to be viewed or edited.
“””
queryset = Product.objects.all().order_by(‘-created_at’)
serializer_class = ProductSerializer

“`

就这么简单!通过继承 ModelViewSet,我们立即获得了 list (GET /products/), create (POST /products/), retrieve (GET /products/{id}/), update (PUT /products/{id}/), partial_update (PATCH /products/{id}/), 和 destroy (DELETE /products/{id}/) 等一系列完整的 CRUD API 操作。

  • queryset: 指定了该视图集将操作的数据集。这里是所有的 Product 对象,并按创建时间倒序排列。
  • serializer_class: 指定了用于序列化和反序列化数据的 Serializer 类。

第四步:配置 URL 路由

Django 的 URLconf 负责将 URL 映射到对应的 View。DRF 为 ViewSet 提供了方便的 Router 类,可以自动为 ViewSet 生成标准的 URL 模式。

打开 myapi_project/urls.py 文件:

“`python

myapi_project/urls.py

from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from products import views

创建一个 Router 实例

router = routers.DefaultRouter()

注册 ProductViewSet 到路由,base_name 通常是 Model 的小写名称

router.register(r’products’, views.ProductViewSet)

urlpatterns = [
path(‘admin/’, admin.site.urls),
# 将 Router 生成的 URL 模式包含进来
path(”, include(router.urls)), # 将 API 根路径设置为 Router 的 URL
# 添加 DRF 提供的登录/登出视图,用于 Browsable API
path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)),
]
“`

这里:

  1. 我们从 rest_framework 导入了 routers
  2. 创建了一个 DefaultRouter 实例。
  3. 使用 router.register() 方法注册了 ProductViewSet。第一个参数是 URL 前缀(如 'products'),第二个参数是 ViewSet 类。DRF 会根据 ViewSet 的操作自动生成 /products/ (列表/创建) 和 /products/{id}/ (详情/更新/删除) 等 URL。
  4. urlpatterns 中,使用 include(router.urls) 将 Router 生成的所有 URL 模式包含进来。我们将其放在根路径 ' 下,所以产品 API 的入口将是 /products/
  5. 添加了 path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))。这会为可浏览的 API 添加登录和登出链接,方便你在浏览器中测试需要认证的 API。

运行服务器并测试

现在,我们可以运行开发服务器并测试我们的第一个 DRF API 了。

bash
python manage.py runserver

打开浏览器,访问 http://127.0.0.1:8000/products/

你应该能看到 DRF 提供的可浏览的 API 界面!

  • 列表页 (/products/): 你可以看到所有产品的数据(如果数据库中有的话)。页面下方会有一个表单,允许你发送 POST 请求来创建新的产品。
  • 详情页 (/products/{id}/): 点击列表中的某个产品,会跳转到其详情页(如 /products/1/)。在这里,你可以看到该产品的详细信息,并可以使用表单发送 PUT、PATCH 或 DELETE 请求来更新或删除该产品。

可浏览的 API 是 DRF 的一个强大特性,它使得 API 的开发、测试和文档化变得非常方便。

你也可以使用其他工具(如 curl、Postman 或 Insomnia)来测试 API。

例如,使用 curl 创建一个新产品:

bash
curl -X POST http://127.0.0.1:8000/products/ \
-H "Content-Type: application/json" \
-d '{"name": "Laptop", "description": "A powerful laptop", "price": 1200.00, "stock": 50}'

使用 curl 获取产品列表:

bash
curl http://127.0.0.1:8000/products/

使用 curl 获取某个产品详情 (假设ID为1):

bash
curl http://127.0.0.1:8000/products/1/

深入 Serializer:验证和字段控制

ModelSerializer 默认会根据 Model 字段进行基本的验证(如必填、数据类型、最大长度等)。但你也可以自定义验证规则。

自定义字段验证:

你可以在 Serializer 中为特定字段编写 validate_<field_name> 方法。

“`python

products/serializers.py

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ‘all

# 验证 stock 字段不能为负数
def validate_stock(self, value):
    if value < 0:
        raise serializers.ValidationError("库存不能为负数。")
    return value

# 验证 price 字段不能为负数
def validate_price(self, value):
    if value < 0:
         raise serializers.ValidationError("价格不能为负数。")
    return value

“`

对象级别验证:

你也可以编写 validate 方法对整个对象的多个字段进行交叉验证。

“`python

products/serializers.py

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ‘all

# ... (字段级别验证方法如 validate_stock, validate_price) ...

# 对象级别验证:例如,如果库存为0,描述必须包含“缺货”
def validate(self, data):
    # data 是一个字典,包含了经过字段级别验证后的所有数据
    stock = data.get('stock', getattr(self.instance, 'stock', None)) # 考虑创建和更新的情况
    description = data.get('description', getattr(self.instance, 'description', ''))

    if stock == 0 and '缺货' not in description:
         raise serializers.ValidationError("库存为0时,描述必须包含 '缺货' 字样。")

    return data # 验证成功必须返回 data

“`

手动控制字段:

除了 __all__fields / exclude,你还可以在 Serializer 中显式定义字段,以自定义其行为、表示方式或添加不存在于 Model 中的字段。

“`python

products/serializers.py

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
# 添加一个只读字段,表示产品的状态
status = serializers.SerializerMethodField()

class Meta:
    model = Product
    fields = ['id', 'name', 'price', 'stock', 'status'] # 确保包含 status 字段

# SerializerMethodField 对应的方法,方法名必须是 get_<field_name>
def get_status(self, obj):
    # obj 是当前序列化的 Product 实例
    if obj.stock > 10:
        return "有库存"
    elif obj.stock > 0:
        return "库存紧张"
    else:
        return "缺货"

# ... (验证方法) ...

“`

通过自定义 Serializer 字段和验证逻辑,你可以精确控制 API 的输入和输出格式以及数据有效性。

身份认证 (Authentication)

默认情况下,我们的 API 是公开的,任何人都可以访问和修改数据。在实际应用中,我们需要保护 API,只允许经过认证的用户进行操作。

DRF 提供了多种认证方案,如:

  • SessionAuthentication: 基于 Django session 的认证,主要用于可浏览的 API 和与你的 Django 网站共享认证状态的场景。
  • TokenAuthentication: 基于 token 的认证,客户端在请求头中发送一个 token 进行认证。适合单页应用或移动应用。
  • BasicAuthentication: 基于 HTTP Basic Authentication,发送用户名和密码。不安全,除非在 HTTPS 环境下使用。
  • RemoteUserAuthentication: 基于 Web 服务器提供的认证信息。

我们以最常用的 TokenAuthentication 为例。

  1. 安装 authtoken 应用:
    settings.pyINSTALLED_APPS 中添加 'rest_framework.authtoken'

    “`python

    myapi_project/settings.py

    INSTALLED_APPS = [
    # … other apps
    ‘rest_framework’,
    ‘rest_framework.authtoken’, # <– 添加 authtoken 应用
    ‘products’,
    ]

    “`

  2. 运行迁移:
    authtoken 应用需要创建数据库表来存储 tokens。

    bash
    python manage.py migrate

  3. 为用户生成 Token:
    你可以通过 Django shell 或创建一个专门的 API 接口来为用户生成 token。最简单的方式是使用 Django shell 或 Django Admin。

    在 shell 中为现有用户生成 token (首先需要创建用户 python manage.py createsuperuser):

    “`bash
    python manage.py shell

    在 shell 中输入以下代码

    from django.contrib.auth.models import User
    from rest_framework.authtoken.models import Token

    获取你想生成token的用户(例如用户名为 ‘admin’)

    user = User.objects.get(username=’admin’)

    为该用户创建或获取token

    token, created = Token.objects.get_or_create(user=user)

    print(token.key) # 打印出生成的token
    exit()
    “`

  4. 应用认证类到 ViewSet:
    products/views.pyProductViewSet 中添加 authentication_classes 属性。

    “`python

    products/views.py

    from rest_framework import viewsets
    from rest_framework.authentication import TokenAuthentication # <– 导入认证类
    from .models import Product
    from .serializers import ProductSerializer

    class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all().order_by(‘-created_at’)
    serializer_class = ProductSerializer
    authentication_classes = [TokenAuthentication] # <– 应用 Token 认证
    # permission_classes 将在下一节讲解
    “`

现在,当你访问 /products//products/{id}/ 端点时,如果没有在请求头中提供有效的 Token,你将收到 401 Unauthorized403 Forbidden 响应(取决于权限设置)。

客户端如何发送 Token?

客户端需要在 HTTP 请求头中添加 Authorization 字段,格式为 Token <你的Token>

例如,使用 curl

bash
curl http://127.0.0.1:8000/products/ \
-H "Authorization: Token 你刚刚生成的token"

权限控制 (Permissions)

认证(Authentication)是确定“你是谁”,而权限(Permission)是确定“你被允许做什么”。即使一个用户通过了认证,他/她也可能没有权限执行某个操作(例如,普通用户不能删除产品)。

DRF 提供了多种权限类,如:

  • AllowAny: 允许任何人访问(默认)。
  • IsAuthenticated: 只允许认证用户访问。
  • IsAdminUser: 只允许管理员用户访问。
  • IsAuthenticatedOrReadOnly: 允许认证用户进行任何操作,未认证用户只能进行安全的方法(GET, HEAD, OPTIONS)。
  • DjangoModelPermissions: 标准 Django django.contrib.auth 模型权限。
  • DjangoObjectPermissions: 基于对象的权限。

你可以将权限类列表添加到 ViewSet 的 permission_classes 属性中。DRF 会按顺序检查这些权限,只要有一个权限通过,请求就被允许。

继续修改 products/views.pyProductViewSet

“`python

products/views.py

from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated # <– 导入权限类
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all().order_by(‘-created_at’)
serializer_class = ProductSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated] # <– 只允许认证用户访问

“`

现在,只有携带有效 Token 的认证用户才能访问 Product API。

更细粒度的权限:

你可能希望普通认证用户可以查看产品列表和详情 (GET),但只有管理员才能创建、更新或删除产品 (POST, PUT, PATCH, DELETE)。可以使用 IsAuthenticatedOrReadOnlyIsAdminUser 的组合来实现。

“`python

products/views.py

from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication

导入多个权限类

from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all().order_by(‘-created_at’)
serializer_class = ProductSerializer
authentication_classes = [TokenAuthentication]
# 权限类列表。按顺序检查。
# 1. 如果是安全方法 (GET, HEAD, OPTIONS),IsAuthenticatedOrReadOnly 允许访问。
# 2. 如果是非安全方法 (POST, PUT, PATCH, DELETE),IsAuthenticatedOrReadOnly 要求认证。
# 3. 如果认证用户是管理员,IsAdminUser 允许访问。
permission_classes = [IsAuthenticatedOrReadOnly, IsAdminUser]

# 可以为不同的动作定义不同的权限
# def get_permissions(self):
#     """
#     Instantiates and returns the list of permissions that this view requires.
#     """
#     if self.action == 'list' or self.action == 'retrieve':
#         permission_classes = [AllowAny] # 允许任何人查看列表和详情
#     else:
#         permission_classes = [IsAdminUser] # 其他操作只允许管理员
#     return [permission() for permission in permission_classes]

“`

上面注释掉的 get_permissions 方法展示了如何在 ViewSet 中为不同的操作(如 list, create, retrieve 等)应用不同的权限策略。通过覆盖 get_permissions 方法,你可以实现非常灵活的权限控制。

分页 (Pagination)

当数据集很大时,一次性返回所有数据会导致性能问题和带宽浪费。分页是处理大型数据集的常用方式,DRF 提供了内置的分页支持。

DRF 提供了多种分页类:

  • PageNumberPagination: 基于页码的分页。
  • LimitOffsetPagination: 基于偏移量和限制数量的分页(类似 SQL 的 LIMIT 和 OFFSET)。
  • CursorPagination: 基于游标的分页,适合大型数据集且需要稳定的分页结果(避免新增或删除数据影响分页)。

我们可以通过在 settings.py 中设置全局默认分页,或者在 View/ViewSet 中单独设置。

全局设置分页 (PageNumberPagination 为例):

“`python

myapi_project/settings.py

… other settings

REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.TokenAuthentication’,
‘rest_framework.authentication.SessionAuthentication’, # 用于 Browsable API 登录
],
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’, # 默认所有 API 需要认证
],
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’, # <– 设置默认分页类
‘PAGE_SIZE’: 10 # <– 每页显示的条目数
}

… other settings

“`

settings.py 中配置后,所有没有单独设置分页的 ViewSet 都会应用这个默认分页。访问 /products/ 将会看到分页结果,可以通过查询参数 ?page=2?page_size=20 (如果允许) 来控制分页。

在 ViewSet 中单独设置分页:

你也可以在 ProductViewSet 中覆盖全局设置或为没有全局设置的 ViewSet 添加分页。

“`python

products/views.py

from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import PageNumberPagination # <– 导入分页类
from .models import Product
from .serializers import ProductSerializer

class ProductPagination(PageNumberPagination): # 可以自定义分页类
page_size = 5 # 每页5条
page_size_query_param = ‘page_size’ # 允许客户端通过 ?page_size= 来控制每页大小
max_page_size = 100 # 最大允许每页显示100条

class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all().order_by(‘-created_at’)
serializer_class = ProductSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
pagination_class = ProductPagination # <– 应用自定义分页类

“`

现在,Product API 将使用 ProductPagination 中定义的规则进行分页。

过滤和搜索 (Filtering & Searching)

除了分页,过滤和搜索也是 API 中常用的功能。DRF 提供了灵活的方式来实现这些功能,通常借助于第三方库 django-filter

  1. 安装 django-filter

    bash
    pip install django-filter

  2. 注册应用:
    settings.pyINSTALLED_APPS 中添加 'django_filter'

    “`python

    myapi_project/settings.py

    INSTALLED_APPS = [
    # … other apps
    ‘rest_framework’,
    ‘rest_framework.authtoken’,
    ‘products’,
    ‘django_filter’, # <– 添加 django_filter
    ]

    “`

  3. 配置 DRF 使用 django-filter
    settings.pyREST_FRAMEWORK 中添加 DEFAULT_FILTER_BACKENDS

    “`python

    myapi_project/settings.py

    REST_FRAMEWORK = {
    # … other settings like authentication, permissions, pagination
    ‘DEFAULT_FILTER_BACKENDS’: [
    ‘django_filters.rest_framework.DjangoFilterBackend’ # <– 添加过滤后端
    ],
    # ‘DEFAULT_SEARCH_BACKENDS’: [ … ], # 如果需要搜索功能,也可以在这里配置
    }
    “`

  4. 在 ViewSet 中指定可过滤字段:
    ProductViewSet 中添加 filter_backendsfilterset_fields 属性。

    “`python

    products/views.py

    from rest_framework import viewsets
    from rest_framework.authentication import TokenAuthentication
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.pagination import PageNumberPagination
    from django_filters.rest_framework import DjangoFilterBackend # <– 导入过滤后端

    from .models import Product
    from .serializers import ProductSerializer

    (可选) 自定义分页类 ProductPagination

    class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all().order_by(‘-created_at’)
    serializer_class = ProductSerializer
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]
    # pagination_class = ProductPagination # (可选) 应用自定义分页类

    # 添加过滤后端
    filter_backends = [DjangoFilterBackend]
    # 指定允许通过 URL 查询参数进行过滤的字段
    filterset_fields = ['name', 'price', 'stock']
    # 例如,访问 /products/?stock=0 将只返回库存为0的产品
    # 访问 /products/?price__gte=1000 将只返回价格大于等于1000的产品 (使用 __gte 进行范围过滤)
    
    # 如果需要简单的搜索功能 (通过一个查询参数搜索多个字段)
    # from rest_framework import filters # 导入搜索后端
    # filter_backends = [DjangoFilterBackend, filters.SearchFilter] # 添加搜索后端
    # search_fields = ['name', 'description'] # 指定可以搜索的字段
    # 例如,访问 /products/?search=laptop 将在 name 和 description 字段中搜索 'laptop'
    
    # 如果需要排序功能
    # from rest_framework import filters # 导入排序后端
    # filter_backends = [DjangoFilterBackend, filters.OrderingFilter] # 添加排序后端
    # ordering_fields = ['name', 'price', 'stock'] # 指定可以排序的字段
    # ordering = ['price'] # 默认按价格升序排序
    # 例如,访问 /products/?ordering=-price 将按价格降序排序
    

“`

现在,你的 Product API 就支持通过 URL 查询参数进行过滤了,例如 /products/?stock=0。通过结合 DjangoFilterBackendfilters.SearchFilterfilters.OrderingFilter,你可以轻松实现强大的数据查询功能。

可浏览的 API 和渲染器 (Renderers)

我们之前已经体验了可浏览的 API。它是 DRF 的一个默认渲染器 (BrowsableAPIRenderer) 的输出。除了 HTML 格式的可浏览 API,DRF 还支持多种渲染器,用于将序列化后的数据转换为不同的格式。

默认情况下,DRF 配置了 JSONRendererBrowsableAPIRenderer。当客户端发送请求时,DRF 会根据请求的 Accept 头来选择合适的渲染器。如果 Accept 头是 application/json,就使用 JSONRenderer 返回 JSON 数据;如果 Accept 头是 text/html 并且是来自浏览器的请求,就可能使用 BrowsableAPIRenderer 返回 HTML 页面。

你可以在 settings.py 中配置默认的渲染器:

“`python

myapi_project/settings.py

REST_FRAMEWORK = {
# … other settings
‘DEFAULT_RENDERER_CLASSES’: [
‘rest_framework.renderers.JSONRenderer’,
‘rest_framework.renderers.BrowsableAPIRenderer’,
],
}
“`

你也可以在 View 或 ViewSet 中覆盖它:

“`python

products/views.py

from rest_framework import viewsets

… other imports

from rest_framework.renderers import JSONRenderer # 导入 JSON 渲染器
from rest_framework.renderers import BrowsableAPIRenderer # 导入 Browsable API 渲染器

class ProductViewSet(viewsets.ModelViewSet):
# … other properties
renderer_classes = [JSONRenderer, BrowsableAPIRenderer] # 明确指定渲染器

“`

这通常在你需要支持除 JSON 和可浏览 API 之外的其他格式时才会修改,例如 XML 或 YAML。

总结和下一步

恭喜你!你已经成功迈入了 Django REST Framework 的大门,并学会了构建一个基础的、具备 CRUD 功能、认证、权限、分页和过滤的 API。

我们回顾一下学到的核心概念:

  • Serializers: 处理数据序列化和反序列化,包括数据验证。ModelSerializer 是最便捷的方式。
  • Views: 处理请求和响应。ModelViewSet 是实现 Model CRUD 操作的高效工具,常与 Router 配合使用。
  • URLs: 通过 DefaultRouter 可以方便地为 ViewSet 生成 URL 模式。
  • Authentication: 验证请求发送者的身份。TokenAuthentication 是常见的 API 认证方式。
  • Permissions: 控制认证用户被允许执行哪些操作。IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly 是常用的权限类。
  • Pagination: 分页处理大型数据集,提高性能。
  • Filtering & Searching: 通过查询参数过滤和搜索数据,通常使用 django-filter
  • Browsable API: 友好的网页界面,方便测试和调试 API。

接下来,你可以继续深入学习:

  • 自定义 Serializer: 学习如何处理嵌套关系、自定义字段和验证逻辑。
  • 自定义 ViewSet actions:ModelViewSet 中添加额外的非 CRUD 操作。
  • 基于函数的 API 视图 (@api_view): 对于非常简单的场景或不需要 Model 的 API,可以使用函数视图。
  • 测试 API: 学习如何使用 Django 的测试框架或 DRF 的测试客户端来测试你的 API 端点。
  • 限流 (Throttling): 限制客户端的请求频率,防止滥用。
  • 版本控制 (Versioning): 如何管理 API 的不同版本。
  • 文档生成: 使用第三方库(如 drf-yasgdrf-spectacular)为 API 生成 Swagger/OpenAPI 文档。
  • 部署 API: 学习如何将你的 Django/DRF 项目部署到生产环境。

Django REST Framework 是一个功能强大的框架,掌握了其核心概念后,你将能够高效地构建各种复杂的 Web API 来支持你的 Web 应用、移动应用或其他服务。不断实践和探索文档是提升技能的最佳途径。

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


发表评论

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

滚动至顶部