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 项目中。
-
安装 DRF:
bash
pip install djangorestframework -
添加到
INSTALLED_APPS
:
在你的 Django 项目的settings.py
文件中,将rest_framework
添加到INSTALLED_APPS
列表中:
“`python
# settings.pyINSTALLED_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’] # 也可以在这里设置只读字段
“`
ModelSerializer
的 Meta
类是关键,它告诉序列化器要关联哪个模型 (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
:ListAPIView
和CreateAPIView
的组合。RetrieveUpdateAPIView
:RetrieveAPIView
和UpdateAPIView
的组合。RetrieveDestroyAPIView
:RetrieveAPIView
和DestroyAPIView
的组合。RetrieveUpdateDestroyAPIView
:RetrieveAPIView
,UpdateAPIView
,DestroyAPIView
的组合。
使用通用视图时,你需要至少指定 queryset
和 serializer_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/
]
“`
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 提供了 Request
和 Response
对象,它们是 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 BookModelSerializerclass 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]
``
get_permissions()` 方法实现更细粒度的权限控制。
视图/ViewSet 级别的配置会覆盖全局配置。你可以通过重写
认证和权限是 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 BookModelSerializerclass 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
“`
-
创建序列化器:
“`python
# myapp/serializers.py
from rest_framework import serializers
from .models import Bookclass BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ‘all‘
“` -
创建 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, OrderingFilterclass 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'] # 允许按出版日期和价格排序
“`
-
配置 URLs 使用路由器:
“`python
# myapp/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import viewsrouter = 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, includeurlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘myapp.urls’)), # 包含应用的 API URL
path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)), # 可选:用于浏览器 API 登录/退出
]
“` -
运行项目:
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 吧!