DRF 介绍指南:认识 Django Rest Framework 的核心概念 – wiki基地


DRF 介绍指南:认识 Django Rest Framework 的核心概念

随着前后端分离、移动应用以及微服务架构的日益流行,构建高效、可维护的 Web API 成为了现代 Web 开发中不可或缺的一部分。Django 作为一款“吃电池”(batteries included)的高级 Python Web 框架,提供了强大的 Web 应用开发能力。然而,Django 原生主要面向传统的服务器端渲染模式,虽然可以手动构建 API 视图,但这通常需要大量的重复工作,比如处理请求/响应格式(尤其是 JSON)、数据序列化与反序列化、用户认证、权限控制、数据过滤和分页等。

Django REST Framework (DRF) 正是为了解决这些痛点而诞生的。它是 Django 的一个强大、灵活的工具包,用于快速构建 Web API。DRF 极大地简化了 API 开发流程,提供了丰富的功能和可扩展性,让开发者能够专注于业务逻辑,而不是底层繁琐的 API 实现细节。

本文将深入探讨 DRF 的核心概念,帮助你全面理解其工作原理和使用方法。

1. 为什么选择 Django REST Framework?

在深入了解 DRF 的具体概念之前,我们先来理解为什么它是构建 Django API 的首选框架:

  • 强大的序列化支持 (Serializers): 轻松将 Django 模型或其他数据类型转换为 JSON/XML 等格式,反之亦然。
  • 灵活的视图层 (Views): 提供多种类型的视图(函数式、类式、通用视图、ViewSets),极大地减少了代码量。
  • 内置的认证和权限系统 (Authentication & Permissions): 方便地实现基于 Session、Token、OAuth2 等多种认证方式,并能细粒度地控制用户对资源的访问权限。
  • 丰富的功能扩展: 内置了过滤 (Filtering)、分页 (Pagination)、限流 (Throttling) 等常用 API 功能。
  • 可浏览的 API (Browsable API): 提供一个友好的 Web 界面,方便开发者和使用者测试和交互 API。
  • 广泛的社区支持和完善的文档: 作为最流行的 Django API 框架,拥有庞大的用户群体和高质量的官方文档。

可以说,DRF 为 Django 开发者提供了一套完整的 API 构建解决方案,让你能够高效地开发出符合 RESTful 原则的高质量 API。

2. RESTful 架构风格简介 (为理解 DRF 做铺垫)

DRF 遵循并鼓励构建 RESTful 风格的 API。理解 REST (Representational State Transfer) 的基本原则对于更好地使用 DRF 至关重要:

  • 无状态 (Stateless): 服务器不存储客户端的会话状态。每次请求必须包含所有必要的信息来完成该请求。
  • 客户端-服务器分离 (Client-Server): 客户端和服务器职责分离,客户端负责用户界面和用户状态管理,服务器负责提供数据和服务。
  • 统一接口 (Uniform Interface): 系统中的资源通过统一的接口进行访问。主要体现在以下几个方面:
    • 资源的标识 (Identification of Resources): 每个资源都有一个唯一的 URI (Uniform Resource Identifier)。
    • 通过表述操作资源 (Manipulation of Resources Through Representations): 客户端通过获取资源的表述(如 JSON、XML)来理解和修改资源的状态。
    • 自描述消息 (Self-descriptive Messages): 每个消息都包含足够的信息来描述如何处理该消息。
    • 超媒体作为应用状态的引擎 (Hypermedia As The Engine Of Application State – HATEOAS): 服务器通过在响应中包含超链接,引导客户端发现可用操作和资源。
  • 分层系统 (Layered System): 客户端无法知道它连接的是最终服务器还是中间代理。
  • 可缓存 (Cacheable): 响应必须明确标示自身是否可被缓存。

在 RESTful API 中,通常使用标准的 HTTP 方法(GET、POST、PUT、PATCH、DELETE)对资源进行操作:

  • GET: 获取资源。
  • POST: 创建资源。
  • PUT: 更新资源(通常是完整更新)。
  • PATCH: 部分更新资源。
  • DELETE: 删除资源。

理解这些原则有助于你理解 DRF 中视图、序列化器等的设计思想。

3. 安装与基础配置

在开始使用 DRF 之前,你需要将其安装到你的 Django 项目中。

  1. 安装 DRF:
    bash
    pip install djangorestframework

  2. 添加到 INSTALLED_APPS:
    在你的 Django 项目的 settings.py 文件中,将 rest_framework 添加到 INSTALLED_APPS 列表中:
    “`python
    # settings.py

    INSTALLED_APPS = [
    # … other apps
    ‘rest_framework’,
    # … your apps
    ]
    “`

完成这两步,DRF 就已经在你的 Django 项目中准备就绪了。

4. 核心概念:序列化器 (Serializers)

序列化器是 DRF 中最核心、最重要的概念之一。它的主要职责是:

  • 将复杂数据类型(如 Django QuerySet、模型实例)转换为易于传输的格式(如 JSON、XML),这个过程称为“序列化 (Serialization)”。
  • 将接收到的格式化数据(如 JSON)验证并转换为复杂数据类型(如模型实例或 Python 字典),这个过程称为“反序列化 (Deserialization)”。

可以把序列化器想象成数据转换器和验证器。

4.1 Serializer

rest_framework.serializers.Serializer 是所有序列化器的基类。你可以手动定义序列化器中的字段,类似于 Django 的 forms.Form

“`python

serializers.py

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True) # 只读字段,通常用于表示模型的ID
title = serializers.CharField(max_length=100)
author = serializers.CharField(max_length=100)
publication_date = serializers.DateField()
price = serializers.DecimalField(max_digits=6, decimal_places=2)

def create(self, validated_data):
    # 实现创建逻辑
    # 例如:Book.objects.create(**validated_data)
    pass

def update(self, instance, validated_data):
    # 实现更新逻辑
    # 例如:instance.title = validated_data.get('title', instance.title)
    # instance.save()
    # return instance
    pass

“`

使用 Serializer 类时,你需要手动实现 create()update() 方法来处理数据的保存。

4.2 ModelSerializer

rest_framework.serializers.ModelSerializer 是最常用的序列化器类。它可以自动推断模型字段,并自动实现 create()update() 方法,极大地简化了代码:

“`python

models.py

from django.db import models

class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
publication_date = models.DateField()
price = models.DecimalField(max_digits=6, decimal_places=2)

def __str__(self):
    return self.title

serializers.py

from rest_framework import serializers
from .models import Book

class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ‘all‘ # 或者指定字段列表:[‘id’, ‘title’, ‘author’, ‘publication_date’, ‘price’]
# read_only_fields = [‘id’] # 也可以在这里设置只读字段
“`

ModelSerializerMeta 类是关键,它告诉序列化器要关联哪个模型 (model) 以及要包含哪些字段 (fields)。fields = '__all__' 表示包含模型的所有字段。

4.3 序列化器的使用流程

无论哪种序列化器,其基本使用流程如下:

  • 序列化 (将对象转为字典):
    python
    # 假设 book_instance 是一个 Book 模型实例
    serializer = BookModelSerializer(book_instance)
    print(serializer.data) # 输出一个 OrderedDict,包含序列化后的数据
    # 如果是 QuerySet
    # books_queryset = Book.objects.all()
    # serializer = BookModelSerializer(books_queryset, many=True) # many=True 用于处理多个对象
    # print(serializer.data) # 输出一个列表,每个元素是序列化后的字典

  • 反序列化 (将数据转为对象):
    python
    # 假设 data 是接收到的数据字典或 QueryDict
    # 例如:{'title': '新的书', 'author': '某作者', 'publication_date': '2023-01-01', 'price': '29.99'}
    serializer = BookModelSerializer(data=data)
    if serializer.is_valid(): # 验证数据是否合法
    # 数据合法,可以通过 .validated_data 访问验证后的数据字典
    # 使用 .save() 方法保存数据(调用 create() 或 update())
    book_instance = serializer.save()
    print(f"创建/更新成功:{book_instance}")
    else:
    # 数据不合法,通过 .errors 访问错误信息
    print(serializer.errors)

    is_valid() 方法会执行字段级别的验证和序列化器级别的 validate() 方法。

4.4 字段与验证

序列化器提供了多种字段类型(如 CharField, IntegerField, DateField, DateTimeField, DecimalField, BooleanField, EmailField, URLField 等),对应不同的数据类型。你也可以自定义字段。

DRF 的验证机制非常强大:

  • 字段级别验证: 在定义字段时可以指定验证器,或通过 validate_字段名() 方法实现。
  • 序列化器级别验证: 通过定义 validate() 方法,可以在所有字段验证通过后执行更复杂的跨字段验证。

“`python

serializers.py 中

class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ‘all

# 字段级别验证示例:确保书名不包含特定词汇
def validate_title(self, value):
    if '禁书' in value:
        raise serializers.ValidationError("书名不能包含敏感词汇。")
    return value

# 序列化器级别验证示例:确保出版日期在今天或之前
def validate(self, data):
    # data 是已经通过字段级别验证的数据字典
    from datetime import date
    if data['publication_date'] > date.today():
         raise serializers.ValidationError({"publication_date": "出版日期不能晚于今天。"})
    return data

“`

通过序列化器,DRF elegantly handles data representation, validation, and persistence logic for your API.

5. 核心概念:视图 (Views)

视图是处理传入请求并返回响应的地方。DRF 提供了多种视图类,从简单的函数式视图到强大的通用视图和 ViewSets。

5.1 函数式 API 视图 (@api_view)

你可以使用 Django 的函数式视图,并用 DRF 提供的 @api_view 装饰器来包装它们。这个装饰器提供了 Request 和 Response 对象、认证、权限、解析器和渲染器支持。

“`python

views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookModelSerializer

@api_view([‘GET’, ‘POST’])
def book_list_create(request):
“””
列出所有书籍或创建一本新书
“””
if request.method == ‘GET’:
books = Book.objects.all()
serializer = BookModelSerializer(books, many=True)
return Response(serializer.data)

elif request.method == 'POST':
    serializer = BookModelSerializer(data=request.data) # request.data 类似 Django 的 request.POST/request.body,已解析
    if serializer.is_valid():
        serializer.save() # 调用 BookModelSerializer 的 create 方法
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view([‘GET’, ‘PUT’, ‘PATCH’, ‘DELETE’])
def book_detail(request, pk):
“””
检索、更新或删除一本特定的书
“””
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)

if request.method == 'GET':
    serializer = BookModelSerializer(book)
    return Response(serializer.data)

elif request.method == 'PUT' or request.method == 'PATCH':
    serializer = BookModelSerializer(book, data=request.data, partial=(request.method == 'PATCH'))
    if serializer.is_valid():
        serializer.save() # 调用 BookModelSerializer 的 update 方法
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

elif request.method == 'DELETE':
    book.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

“`
函数式视图适用于简单的场景或只需要少量 HTTP 方法的情况,但对于标准的 CRUD (Create, Retrieve, Update, Delete) 操作,代码会显得重复。

5.2 类式 API 视图 (APIView)

rest_framework.views.APIView 是 DRF 类式视图的基类。它提供了与 Django View 类似的结构,可以为不同的 HTTP 方法定义不同的方法(如 .get(), .post(), .put(), .patch(), .delete())。APIView 同样提供了 DRF 的核心功能支持。

“`python

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404 # DRF APIView 也能处理 Django 的异常
from .models import Book
from .serializers import BookModelSerializer

class BookListCreateAPIView(APIView):
“””
列出所有书籍或创建一本新书
“””
def get(self, request, format=None):
books = Book.objects.all()
serializer = BookModelSerializer(books, many=True)
return Response(serializer.data)

def post(self, request, format=None):
    serializer = BookModelSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class BookDetailAPIView(APIView):
“””
检索、更新或删除一本特定的书
“””
def get_object(self, pk):
try:
return Book.objects.get(pk=pk)
except Book.DoesNotExist:
raise Http404 # DRF 会将其转换为 404 Response

def get(self, request, pk, format=None):
    book = self.get_object(pk)
    serializer = BookModelSerializer(book)
    return Response(serializer.data)

def put(self, request, pk, format=None):
    book = self.get_object(pk)
    serializer = BookModelSerializer(book, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def patch(self, request, pk, format=None):
    book = self.get_object(pk)
    serializer = BookModelSerializer(book, data=request.data, partial=True) # partial=True 允许部分更新
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


def delete(self, request, pk, format=None):
    book = self.get_object(pk)
    book.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

“`
类式视图比函数式视图更结构化,更适合组织复杂的逻辑。

5.3 通用 API 视图 (Generic API Views)

DRF 提供了一系列通用视图类,它们构建在 APIView 之上,并混入了(Mixin)处理常见操作(如列表、创建、检索、更新、删除)的功能。使用通用视图可以进一步减少代码。

核心的通用视图包括:

  • ListAPIView: 用于列出资源。
  • CreateAPIView: 用于创建资源。
  • RetrieveAPIView: 用于检索单个资源。
  • UpdateAPIView: 用于更新单个资源(PUT/PATCH)。
  • DestroyAPIView: 用于删除单个资源。
  • ListCreateAPIView: ListAPIViewCreateAPIView 的组合。
  • RetrieveUpdateAPIView: RetrieveAPIViewUpdateAPIView 的组合。
  • RetrieveDestroyAPIView: RetrieveAPIViewDestroyAPIView 的组合。
  • RetrieveUpdateDestroyAPIView: RetrieveAPIView, UpdateAPIView, DestroyAPIView 的组合。

使用通用视图时,你需要至少指定 querysetserializer_class 属性。

“`python

views.py

from rest_framework import generics # 导入通用视图模块
from .models import Book
from .serializers import BookModelSerializer

class BookListCreateGenericView(generics.ListCreateAPIView):
“””
使用通用视图列出所有书籍或创建一本新书
“””
queryset = Book.objects.all() # 指定查询集
serializer_class = BookModelSerializer # 指定使用的序列化器

class BookRetrieveUpdateDestroyGenericView(generics.RetrieveUpdateDestroyAPIView):
“””
使用通用视图检索、更新或删除一本特定的书
“””
queryset = Book.objects.all() # 指定查询集(用于get_object查找)
serializer_class = BookModelSerializer # 指定使用的序列化器
# lookup_field = ‘pk’ # 默认就是pk,如果想用slug或其他字段,可以设置
“`
可以看到,使用通用视图极大地简化了代码,对于标准的 CRUD 接口,这是非常高效的方式。

5.4 ViewSets (视图集)

ViewSets 是 DRF 中最高级的视图抽象。一个 ViewSet 可以处理一组相关的视图逻辑,如列出、创建、检索、更新和删除一个模型。它将多个视图的功能合并到一个类中。ViewSets 通常与 DRF 的路由器 (Routers) 一起使用,自动生成 URL 配置。

核心的 ViewSet 包括:

  • ViewSet: 最基本的 ViewSet,你需要手动定义行为方法(如 list, create, retrieve, update, partial_update, destroy)。
  • ModelViewSet: 构建在 ViewSet 之上,并混入了所有标准的 CRUD 操作的 Mixin。这是最常用于模型资源的 ViewSet。

“`python

views.py

from rest_framework import viewsets # 导入 ViewSet 模块
from .models import Book
from .serializers import BookModelSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly # 稍后介绍权限

class BookModelViewSet(viewsets.ModelViewSet):
“””
使用 ModelViewSet 处理书籍资源的 CRUD 操作
“””
queryset = Book.objects.all() # 指定查询集
serializer_class = BookModelSerializer # 指定使用的序列化器
# permission_classes = [IsAuthenticatedOrReadOnly] # 稍后介绍如何应用权限
# filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] # 稍后介绍过滤/搜索/排序
# pagination_class = PageNumberPagination # 稍后介绍分页
``ModelViewSet自动提供了list,create,retrieve,update,partial_update,destroy` 等方法。你无需像通用视图那样为每个操作定义一个单独的类。

6. 核心概念:URLs 和 路由 (Routing)

定义了视图后,需要将它们映射到 URL。DRF 为 ViewSets 提供了方便的路由器。

6.1 手动映射 URLs (对于函数式视图或 APIView/Generic Views)

对于函数式视图或基于 APIView/Generic Views 的类式视图,你可以像在标准 Django 中一样,手动在 urls.py 中定义 URL 模式:

“`python

urls.py (in your app)

from django.urls import path
from . import views

urlpatterns = [
path(‘books/’, views.BookListCreateGenericView.as_view(), name=’book-list-create’),
path(‘books//’, views.BookRetrieveUpdateDestroyGenericView.as_view(), name=’book-detail’),
]
“`

6.2 使用路由器 (Routers) (对于 ViewSets)

对于 ViewSets,DRF 提供了路由器,可以根据 ViewSet 自动生成 URL 模式。这是使用 ViewSets 的推荐方式。

“`python

urls.py (in your app)

from django.urls import path, include
from rest_framework.routers import DefaultRouter # 或 SimpleRouter
from . import views

创建一个路由器实例

router = DefaultRouter()

注册 ViewSet 到路由器

第一个参数是 URL 前缀,第二个参数是 ViewSet 类,第三个参数是 URL 名称的基础(可选)

router.register(r’books’, views.BookModelViewSet, basename=’book’)

URLs 现在由路由器自动生成

urlpatterns = [
# … other urls if any
path(”, include(router.urls)), # 将路由器生成的 URL 包含进来
]

如果是项目的主 urls.py,可能需要再嵌套一层

project/urls.py

from django.contrib import admin

from django.urls import path, include

from . import router # 假设你的应用的 urls.py 文件名是 router.py

urlpatterns = [

path(‘admin/’, admin.site.urls),

path(‘api/’, include(‘myapp.urls’)), # 或者直接包含路由器

# path(‘api/’, include(router.urls)), # 如果路由器在项目urls.py中定义

]

``DefaultRouter会自动为ModelViewSet生成list,create,retrieve,update,partial_update,destroy等操作对应的 URL。例如,/books/(GET/POST) 和/books/{pk}/` (GET/PUT/PATCH/DELETE)。

7. 核心概念:请求 (Request) 和响应 (Response)

DRF 提供了 RequestResponse 对象,它们是 DRF 视图的核心。

  • Request 对象: 它是 Django 标准 HttpRequest 对象的子类,但提供了更灵活的 API 请求处理能力。

    • request.data: 智能地处理请求体数据。它可以处理 POST、PUT、PATCH 请求中的 JSON、表单数据等,并已解析成 Python 数据结构。
    • request.query_params: 类似于 Django 的 request.GET,用于访问 URL 中的查询参数。
    • request.method: 获取 HTTP 方法。
    • request.user: 当前认证用户。
    • request.auth: 当前认证凭据。
  • Response 对象: 它是 DRF 提供的 Response 类实例,而不是 Django 的 HttpResponse。它可以接受各种 Python 数据类型,并根据客户端请求的 Accept 头部(以及配置的渲染器)自动渲染成 JSON、HTML 等格式。

    • Response(data, status=None, template_name=None, headers=None, content_type=None)
    • data: 要序列化的数据。
    • status: HTTP 状态码(推荐使用 rest_framework.status 模块中的常量,如 status.HTTP_200_OK, status.HTTP_201_CREATED)。

使用 Response 对象是 DRF 视图返回数据的主要方式。

“`python

views.py (使用 Response 的例子)

from rest_framework.response import Response
from rest_framework import status

def my_api_view(request):
if request.method == ‘GET’:
# 假设 some_data 是一个 Python 字典或列表
some_data = {‘message’: ‘Hello, API!’, ‘items’: [1, 2, 3]}
return Response(some_data, status=status.HTTP_200_OK)
elif request.method == ‘POST’:
# 访问解析后的请求体数据
received_data = request.data
# … 处理数据 …
return Response({‘status’: ‘success’, ‘received’: received_data}, status=status.HTTP_201_CREATED)
“`

8. 核心概念:认证 (Authentication) 与权限 (Permissions)

安全是 API 开发的重中之重。DRF 提供了灵活且强大的认证和权限系统。

  • 认证 (Authentication): 验证请求的发送者是谁。它标识用户。DRF 支持多种认证方式:

    • SessionAuthentication: 基于 Django Session 的认证,适用于与基于浏览器的会话集成。
    • TokenAuthentication: 基于简单 Token 的认证,适用于移动应用或第三方客户端。
    • BasicAuthentication: HTTP Basic 认证。
    • OAuth2Authentication: OAuth2 认证(需要安装第三方库如 django-oauth-toolkit)。
  • 权限 (Permissions): 确定经过认证的用户是否有权执行请求的操作。它控制用户能做什么。DRF 提供多种权限类:

    • AllowAny: 允许所有用户访问(默认)。
    • IsAuthenticated: 只允许认证用户访问。
    • IsAdminUser: 只允许管理员用户 (is_staff=True) 访问。
    • IsAuthenticatedOrReadOnly: 允许认证用户完全访问,未认证用户只读。
    • DjangoModelPermissions: 基于 Django 的模型权限 (add, change, delete等) 控制访问。
    • DjangoObjectPermissions: 基于 Django 的对象级别权限控制访问(需要后端支持,如 django-guardian)。

8.1 如何应用认证和权限

你可以在全局配置中设置默认的认证和权限类,也可以在单个视图或 ViewSet 中进行配置。

  • 全局配置 (settings.py):
    python
    # settings.py
    REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
    'rest_framework.authentication.TokenAuthentication',
    'rest_framework.authentication.SessionAuthentication', # 可以配置多种认证方式
    ],
    'DEFAULT_PERMISSION_CLASSES': [
    'rest_framework.permissions.IsAuthenticated', # 默认只允许认证用户访问
    ]
    }

  • 视图/ViewSet 级别配置:
    “`python
    # views.py
    from rest_framework import viewsets
    from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser
    from .models import Book
    from .serializers import BookModelSerializer

    class BookModelViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
    # 视图级别设置权限,覆盖全局配置
    permission_classes = [IsAuthenticatedOrReadOnly]

    # 也可以针对特定动作设置不同的权限
    # def get_permissions(self):
    #     if self.action == 'create':
    #         self.permission_classes = [IsAdminUser] # 创建需要管理员权限
    #     elif self.action == 'list':
    #          self.permission_classes = [AllowAny] # 列表允许所有人访问
    #     else:
    #          self.permission_classes = [IsAuthenticatedOrReadOnly]
    #     return [permission() for permission in self.permission_classes]
    

    ``
    视图/ViewSet 级别的配置会覆盖全局配置。你可以通过重写
    get_permissions()` 方法实现更细粒度的权限控制。

认证和权限是 API 安全的基础,DRF 提供的系统非常灵活,可以满足大多数需求,也可以自定义认证和权限类。

9. 核心概念:渲染器 (Renderers) 与解析器 (Parsers)

  • 解析器 (Parsers): DRF 使用解析器来解析请求体 (request.data)。它们根据请求的 Content-Type 头部决定如何解析数据。

    • JSONParser: 处理 application/json 请求。
    • FormParser: 处理标准 HTML 表单提交的 'application/x-www-form-urlencoded'
    • MultiPartParser: 处理多部分表单数据 'multipart/form-data' (用于文件上传)。
  • 渲染器 (Renderers): DRF 使用渲染器来格式化响应数据 (response.data)。它们根据请求的 Accept 头部决定如何格式化响应。

    • JSONRenderer: 将数据渲染成 JSON 格式。
    • BrowsableAPIRenderer: 将数据渲染成可浏览的 HTML 页面,提供了友好的 Web 界面。
    • HTMLFormRenderer: 用于在可浏览 API 中渲染表单。

你可以在全局或视图级别配置解析器和渲染器:

“`python

settings.py (全局配置示例)

REST_FRAMEWORK = {
# … authentication, permission, etc.
‘DEFAULT_PARSER_CLASSES’: [
‘rest_framework.parsers.JSONParser’,
‘rest_framework.parsers.FormParser’,
‘rest_framework.parsers.MultiPartParser’,
],
‘DEFAULT_RENDERER_CLASSES’: [
‘rest_framework.renderers.JSONRenderer’,
‘rest_framework.renderers.BrowsableAPIRenderer’, # 启用可浏览 API
]
}

views.py (视图级别配置示例)

from rest_framework.views import APIView
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

class OnlyJSONAPIView(APIView):
renderer_classes = [JSONRenderer] # 只允许 JSON 响应
parser_classes = [JSONParser] # 只允许 JSON 请求体
# … view logic …
“`
通过配置解析器和渲染器,DRF 可以支持多种数据格式的 API 交互。

10. 核心概念:分页 (Pagination)

当返回大量数据时,一次性全部返回会影响性能和用户体验。分页是必要的。DRF 提供了多种分页类:

  • PageNumberPagination: 基于页码和每页大小进行分页。客户端通过 ?page=X&size=Y?page=X&page_size=Y 控制。
  • LimitOffsetPagination: 基于偏移量和限制数量进行分页。客户端通过 ?limit=X&offset=Y 控制。
  • CursorPagination: 基于游标的分页,适用于大型数据集和无限滚动的场景,更适合保证排序一致性,但不能跳页。

配置分页可以在全局或视图级别进行。

  • 全局配置 (settings.py):
    python
    # settings.py
    REST_FRAMEWORK = {
    # ... other settings
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10 # 默认每页大小
    }

  • 视图/ViewSet 级别配置:
    “`python
    # views.py
    from rest_framework import viewsets
    from rest_framework.pagination import LimitOffsetPagination
    from .models import Book
    from .serializers import BookModelSerializer

    class BookModelViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
    pagination_class = LimitOffsetPagination # 在这个 ViewSet 中使用 LimitOffsetPagination
    # 如果使用 PageNumberPagination,也可以在这里设置 page_size
    # pagination_class = PageNumberPagination
    # page_size = 20 # 这个 ViewSet 每页20条
    “`
    应用分页后,列表视图的响应会自动包含分页信息(如总数、下一页/上一页链接、当前页数据)。

11. 核心概念:可浏览的 API (Browsable API)

这是 DRF 的一个非常出色的特性。当你在设置中启用了 BrowsableAPIRenderer (默认是启用的),并在浏览器中访问你的 API 端点时,你会看到一个漂亮的 HTML 页面,而不是原始 JSON 数据。这个页面提供了:

  • 资源的清晰展示。
  • 表单用于 POST、PUT、PATCH 操作,方便测试。
  • 认证、权限、过滤、分页等信息的提示。

可浏览 API 极大地提高了 API 的可测试性和可用性,是开发过程中不可或缺的工具。

12. 其他重要概念 (简述)

  • 过滤 (Filtering): 允许客户端通过查询参数过滤结果集。DRF 支持简单的基于字段过滤,更复杂的需求常使用 django-filter 库。
  • 搜索 (Search): 允许客户端通过查询参数搜索结果集中的文本内容。
  • 排序 (Ordering): 允许客户端通过查询参数指定结果集的排序方式。
  • 异常处理 (Exception Handling): DRF 提供了统一的异常处理机制,将 Django 或 DRF 内部的异常转换为标准的 HTTP 响应(如 400 Bad Request, 404 Not Found, 500 Internal Server Error)。
  • 字段 (Fields): 除了基本的字段类型,DRF 还支持关系字段(如 PrimaryKeyRelatedField, StringRelatedField, SlugRelatedField, HyperlinkedModelSerializer)来处理模型之间的关系。
  • 自定义: DRF 的每个组件都设计为可插拔和可自定义,你可以创建自定义的序列化器字段、验证器、解析器、渲染器、认证类、权限类、过滤类、分页类等。

13. 构建一个简单的例子:书籍 API (回顾与整合)

让我们将上面提到的一些核心概念整合起来,构建一个简单的书籍 API。

假设我们有前面定义的 Book 模型:

“`python

myapp/models.py

from django.db import models

class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
publication_date = models.DateField()
price = models.DecimalField(max_digits=6, decimal_places=2)

def __str__(self):
    return self.title

“`

  1. 创建序列化器:
    “`python
    # myapp/serializers.py
    from rest_framework import serializers
    from .models import Book

    class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
    model = Book
    fields = ‘all
    “`

  2. 创建 ViewSet:
    “`python
    # myapp/views.py
    from rest_framework import viewsets
    from .models import Book
    from .serializers import BookModelSerializer
    from rest_framework.permissions import IsAuthenticatedOrReadOnly
    from rest_framework.pagination import PageNumberPagination
    # 过滤/搜索/排序需要安装 django-filter 并添加到 INSTALLED_APPS
    # pip install django-filter
    # INSTALLED_APPS = [‘django_filters’, …]
    # from django_filters.rest_framework import DjangoFilterBackend
    # from rest_framework.filters import SearchFilter, OrderingFilter

    class BookPagination(PageNumberPagination):
    page_size = 5 # 设置这个 ViewSet 的默认每页大小
    page_size_query_param = ‘page_size’ # 允许客户端通过 ?page_size=X 控制
    max_page_size = 100 # 客户端能请求的最大每页大小

    class BookModelViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all().order_by(‘id’) # 通常需要一个默认排序
    serializer_class = BookModelSerializer
    permission_classes = [IsAuthenticatedOrReadOnly] # 只读允许所有人,增删改需要认证
    pagination_class = BookPagination # 使用自定义分页类

    # 配置过滤、搜索、排序 (需要安装 django-filter)
    # filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    # filterset_fields = ['author', 'publication_date'] # 允许按作者和出版日期过滤
    # search_fields = ['title', 'author'] # 允许按书名和作者搜索
    # ordering_fields = ['publication_date', 'price'] # 允许按出版日期和价格排序
    

    “`

  3. 配置 URLs 使用路由器:
    “`python
    # myapp/urls.py
    from django.urls import path, include
    from rest_framework.routers import DefaultRouter
    from . import views

    router = DefaultRouter()
    router.register(r’books’, views.BookModelViewSet) # basename 可以省略,DRF 会根据 queryset 自动推断

    urlpatterns = [
    path(”, include(router.urls)),
    # 可以在这里添加其他非 ViewSet 的 URL,例如认证 URL
    # path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)),
    ]

    项目的主 urls.py 包含应用的 urls

    project/urls.py

    from django.contrib import admin
    from django.urls import path, include

    urlpatterns = [
    path(‘admin/’, admin.site.urls),
    path(‘api/’, include(‘myapp.urls’)), # 包含应用的 API URL
    path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)), # 可选:用于浏览器 API 登录/退出
    ]
    “`

  4. 运行项目:
    bash
    python manage.py migrate # 确保模型已同步到数据库
    python manage.py createsuperuser # 创建管理员用户以测试权限
    python manage.py runserver

    访问 http://127.0.0.1:8000/api/books/ (假设你的 API 前缀是 /api/),你将看到 DRF 的可浏览 API 界面,你可以添加书籍、查看列表、点击书籍详情进行查看、更新或删除。

14. 总结与展望

Django REST Framework 是构建 Django Web API 的强大而优雅的解决方案。通过本文对序列化器、视图(特别是通用视图和 ViewSets)、URLs/路由器、请求/响应、认证/权限、渲染器/解析器、分页等核心概念的详细介绍,你应该对 DRF 的基本工作原理和使用方式有了全面的认识。

DRF 通过提供高级抽象和可重用组件,极大地减少了开发 API 所需的代码量,并鼓励遵循 RESTful 设计原则。同时,其灵活的架构允许你在需要时深入底层或进行广泛的自定义。

这只是 DRF 的冰山一角,框架还提供了许多其他功能和高级用法,例如:

  • 关系序列化字段的更多用法
  • 自定义字段和序列化器
  • 基于 Signal 的序列化器 save 钩子
  • 更复杂的过滤、搜索、排序实现
  • 版本控制 (Versioning)
  • 限流 (Throttling)
  • 自定义异常处理
  • Schema/Swagger/OpenAPI 文档生成 (如 drf-spectacular)
  • 与 GraphQL 等其他技术的集成

掌握了这些核心概念,你就为进一步探索 DRF 的高级功能和构建复杂 API 奠定了坚实的基础。现在,开始动手实践,构建你自己的 Django RESTful API 吧!


发表评论

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

滚动至顶部