Django API 开发利器:Django REST Framework 详细介绍
随着互联网应用的日益复杂,前后端分离、移动应用、微服务架构等模式已成为主流。在这些模式下,高效、安全、可维护的 Web API 成为了连接不同部分的关键桥梁。对于使用 Django 框架的开发者来说,如何快速而优雅地构建 RESTful API 是一个常见的挑战。幸运的是,有一个强大的工具应运而生,它就是 Django REST Framework (DRF)。
Django REST Framework 是一个灵活且功能强大的工具集,用于快速构建 Web API。它建立在 Django 框架之上,充分利用了 Django 的优秀特性(如 ORM、URL dispatcher、Auth 系统等),并为其增加了 API 开发所需的各种便利功能。毫不夸张地说,DRF 是 Django 生态系统中用于 API 开发的事实标准。
本文将深入探讨 Django REST Framework,介绍其核心概念、主要组件、如何使用它构建 API,以及为什么它成为 Django API 开发的首选工具。
一、为什么需要 Django REST Framework?
在没有 DRF 的情况下,使用原生 Django 开发 API 可能会面临一些挑战:
- 数据序列化与反序列化: 从 Django 模型对象转换为 JSON 或 XML 等 API 常见格式,以及将接收到的 JSON/XML 数据转换回 Django 模型对象进行保存,需要手动编写大量重复的代码。
- 请求与响应处理: 处理 HTTP 请求的各种方法(GET, POST, PUT, DELETE 等),解析请求体,构建符合 API 规范的响应体(设置状态码、头部信息等),都需要手动实现。
- 认证与权限控制: 确保只有授权用户才能访问特定资源,以及控制用户对资源的具体操作(读、写、删等),需要集成认证系统并手动进行权限检查。
- 版本控制、限流、分页等高级功能: 实现这些功能往往需要额外的代码和逻辑。
- 一致性和规范性: 在大型项目中,如果没有一个统一的框架,团队成员编写的 API 接口容易出现不一致的情况。
Django REST Framework 旨在解决这些痛点,它提供了一套成熟的解决方案,让开发者能够专注于业务逻辑,而不是底层繁琐的 API 实现细节。
二、什么是 Django REST Framework?
Django REST Framework 是一个建立在 Django 之上的第三方库,它为构建 RESTful API 提供了一系列强大且灵活的抽象。它的目标是:
- 让 API 开发变得简单、快速。
- 提供一个统一的、规范的 API 开发模式。
- 提供丰富的功能,如认证、权限、限流、分页等。
- 提供优秀的文档和社区支持。
- 拥有一个非常实用的浏览器化 API (Browsable API),方便开发者和API使用者进行测试和交互。
DRF 并非取代 Django,而是增强了 Django 在 API 开发方面的能力。你可以继续使用 Django 的 ORM、模板(如果你需要)、Admin 后台等功能,同时利用 DRF 来构建你的 API 层。
三、Django REST Framework 的核心组件
DRF 强大功能的背后是一系列精心设计的核心组件,它们协同工作,构成了 DRF 的整个体系。理解这些组件是掌握 DRF 的关键。
1. Serializers (序列化器)
这是 DRF 中最核心的概念之一。序列化器用于定义如何将复杂数据类型(如 Django 模型实例、查询集)转换为可以轻松传输的标准格式(如 JSON、XML),以及如何将接收到的标准格式数据反序列化回复杂数据类型,并进行数据验证。
- 作用:
- 将数据库中的模型对象序列化为 JSON 等格式,供 API 响应使用。
- 将接收到的请求数据(如 JSON)反序列化为 Python 数据,并验证数据的有效性,以便创建或更新数据库对象。
- 类型:
Serializer
: 更通用的序列化器,适用于处理任意数据。ModelSerializer
: 基于 Django 模型自动生成字段的序列化器,大大简化了模型序列化器的编写。它会自动包含模型的字段,并且可以轻松处理关联关系。
示例 (使用 ModelSerializer):
假设我们有一个简单的 Django 模型:
“`python
models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(‘auth.User’, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
“`
我们可以为其创建一个 ModelSerializer
:
“`python
serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
# 可以自定义字段,比如显示作者用户名而不是ID
author = serializers.ReadOnlyField(source=’author.username’)
class Meta:
model = Article
fields = ['id', 'title', 'content', 'author', 'created_at'] # 指定需要序列化的字段
# 或者使用 '__all__' 包含所有字段,但通常不推荐
# fields = '__all__'
# read_only_fields = ['created_at'] # 指定只读字段
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [‘id’, ‘username’]
“`
使用 Serializer 的流程 (反序列化):
- 创建序列化器实例,传入待验证和反序列化的数据:
serializer = ArticleSerializer(data=request.data)
- 调用
.is_valid()
进行数据验证:if serializer.is_valid():
- 访问验证后的数据:
validated_data = serializer.validated_data
- 保存数据(如果用于创建/更新对象):
serializer.save()
(ModelSerializer 会自动处理创建或更新)
使用 Serializer 的流程 (序列化):
- 创建序列化器实例,传入要序列化的对象或查询集:
serializer = ArticleSerializer(article_instance)
或serializer = ArticleSerializer(article_list, many=True)
(many=True 用于处理多个对象) - 访问序列化后的数据:
data = serializer.data
2. Views (视图)
DRF 的视图是处理请求和返回响应的核心逻辑所在。DRF 提供了一系列视图基类,简化了 API 视图的编写。
APIView
:- 这是 DRF 中最基本的视图类,它继承自 Django 的
View
类。 - 它提供了更高级的功能,例如:
- 处理传入的请求,解析
request.data
(根据请求的 Content-Type 自动解析 JSON, XML 等)。 - 格式化传出的响应,使用
Response
对象 (根据请求的 Accept 头部自动选择渲染器,如 JSONRenderer)。 - 提供了认证、权限、限流等功能钩子。
- 处理传入的请求,解析
- 你需要像 Django 的 Class-Based Views 一样,为不同的 HTTP 方法(GET, POST, PUT, DELETE 等)定义相应的方法。
- 这是 DRF 中最基本的视图类,它继承自 Django 的
示例 (使用 APIView):
“`python
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer
class ArticleListAPIView(APIView):
def get(self, request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request):
serializer = ArticleSerializer(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)
“`
- Generic API Views (通用视图):
- DRF 提供了一组强大的通用视图类,它们封装了常见的 API 操作,如列表、创建、详情、更新、删除等。
- 这些通用视图结合了 Mixins (混合类) 来提供具体的操作逻辑。例如,
ListModelMixin
提供了列表功能,CreateModelMixin
提供了创建功能。 - 通过继承这些通用视图和 Mixins,可以快速实现标准的 CRUD (创建、读取、更新、删除) 接口,而无需编写大量重复代码。
- 常见的通用视图类:
generics.CreateAPIView
(创建对象)generics.ListAPIView
(获取对象列表)generics.RetrieveAPIView
(获取单个对象详情)generics.UpdateAPIView
(更新单个对象)generics.DestroyAPIView
(删除单个对象)generics.ListCreateAPIView
(获取列表和创建)generics.RetrieveUpdateDestroyAPIView
(获取详情、更新、删除)
示例 (使用 Generic API Views):
“`python
views.py
from rest_framework import generics
from .models import Article
from .serializers import ArticleSerializer
class ArticleListCreate(generics.ListCreateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class ArticleRetrieveUpdateDestroy(generics.RetrieveUpdateDestroyAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = ‘pk’ # 指定查找对象的字段,默认为pk
“`
3. ViewSets (视图集)
视图集是 DRF 中另一个重要的概念,它将一组相关的视图逻辑(通常是针对同一个模型或资源)组合到一个类中。一个视图集可以包含 list
, create
, retrieve
, update
, partial_update
, destroy
等操作。
- 作用: 将针对一个资源的多个 API 操作(如获取列表、获取详情、创建、更新、删除)放在一个类中管理,使代码更紧凑、更有条理。
- 与 Views 的区别: Views 侧重于处理特定的 HTTP 方法 (GET, POST 等),而 ViewSets 侧重于处理一组相关的操作 (list, create, retrieve 等)。ViewSets 通常与 Routers 配合使用,自动生成 URL 路由。
- 类型:
ViewSet
: 更通用的视图集基类。ModelViewSet
: 基于 Django 模型自动提供list
,create
,retrieve
,update
,partial_update
,destroy
操作的视图集,是最常用的视图集类型。
示例 (使用 ModelViewSet):
“`python
views.py
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly # 示例权限
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
# 可以直接在这里配置权限、认证、过滤等
permission_classes = [IsAuthenticatedOrReadOnly] # 例如,登录用户可写,匿名用户只读
“`
4. Routers (路由器)
当使用 ViewSets 时,通常需要将视图集中的操作映射到 URL。DRF 的 Routers 可以自动完成这项工作,根据 ViewSet 定义的标准操作(list, retrieve 等)自动生成对应的 URL 模式。
- 类型:
SimpleRouter
: 提供一个简单的默认 URL 模式。DefaultRouter
: 提供了更丰富的默认模式,包括根视图和格式后缀模式,并支持浏览器化 API。
示例 (使用 DefaultRouter):
“`python
urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views # 假设ArticleViewSet在views.py中
创建路由器实例
router = DefaultRouter()
注册视图集,’articles’ 是 URL 前缀,views.ArticleViewSet 是对应的视图集
router.register(r’articles’, views.ArticleViewSet)
‘basename’ 参数可以显式指定URL名称的前缀,通常在queryset没有.model属性时需要
urlpatterns = [
# 将路由器生成的URL模式包含进来
path(”, include(router.urls)),
# 也可以添加其他非ViewSet的URL模式
# path(‘custom-api/’, views.CustomAPIView.as_view()),
]
“`
使用 DefaultRouter
注册 ArticleViewSet
后,它会自动生成类似以下 URL 模式:
/articles/
(GET: list, POST: create)/articles/{pk}/
(GET: retrieve, PUT: update, PATCH: partial_update, DELETE: destroy)
5. Authentication & Permissions (认证与权限)
DRF 提供了灵活的认证和权限系统来保护你的 API。
- Authentication (认证): 验证请求的发出者是谁(用户或客户端)。DRF 支持多种认证方式:
SessionAuthentication
: 基于 Django session 的认证,适合与 Django 模板渲染的前端结合或浏览器化 API。TokenAuthentication
: 基于 Token 的认证,适合无状态的 API 客户端(如移动应用、SPA)。BasicAuthentication
: 基于 HTTP Basic 头部认证。- 你也可以实现自定义的认证方式。
- Permissions (权限): 在认证之后,决定发出请求的用户是否有权执行请求的操作(例如,是否有权查看、修改或删除某个对象)。DRF 提供了多种权限类:
AllowAny
: 允许所有用户访问。IsAuthenticated
: 只允许认证用户访问。IsAdminUser
: 只允许管理员用户访问。IsAuthenticatedOrReadOnly
: 认证用户有完全权限,匿名用户只有只读权限。DjangoModelPermissions
: 基于 Django 的django.contrib.auth
模型权限。DjangoObjectPermissions
: 基于 Django 的对象级别权限。- 你也可以实现自定义的权限类。
配置方式: 可以在全局设置中配置默认的认证和权限类,也可以在视图或视图集级别单独配置。
“`python
settings.py (全局配置示例)
REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.TokenAuthentication’,
‘rest_framework.authentication.SessionAuthentication’, # 通常也保留以便浏览器化API使用
],
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’, # 默认只允许认证用户访问
],
# … 其他设置
}
views.py (视图级别配置示例)
class ArticleViewSet(viewsets.ModelViewSet):
# …
authentication_classes = [TokenAuthentication] # 仅使用Token认证
permission_classes = [IsAuthenticatedOrReadOnly] # 特定权限
“`
6. Parsers & Renderers (解析器与渲染器)
- Parsers (解析器): 负责解析请求体的数据(如 JSON, XML, 表单数据),将其转换为 Python 数据结构 (
request.data
)。 - Renderers (渲染器): 负责将视图返回的 Python 数据(
Response
对象的数据)渲染成特定格式的响应体(如 JSON, HTML 用于浏览器化 API),并设置 Content-Type 头部。
DRF 默认支持 JSONParser
和 FormParser
等,默认渲染器包括 JSONRenderer
和 BrowsableAPIRenderer
。你也可以添加对 XML 或其他格式的支持。
7. Pagination (分页)
处理大型数据集时,分页是必不可少的。DRF 提供了多种分页类,可以轻松地对列表视图进行分页。
PageNumberPagination
: 基于页码和每页数量的分页。LimitOffsetPagination
: 基于偏移量和限制数量的分页。CursorPagination
: 基于游标的分页,适用于超大型数据集且需要稳定排序的场景。
配置方式: 可以在全局设置中配置默认分页,也可以在视图或视图集级别配置。
“`python
settings.py (全局配置示例)
REST_FRAMEWORK = {
# …
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10 # 默认每页数量
}
views.py (视图级别配置示例)
class ArticleList(generics.ListAPIView):
# …
pagination_class = LimitOffsetPagination # 使用不同的分页方式
“`
8. Throttling (限流)
限流用于控制客户端或用户在特定时间内可以发出的请求次数,防止滥用或拒绝服务攻击。
AnonRateThrottle
: 限制匿名用户的请求速率。UserRateThrottle
: 限制认证用户的请求速率。ScopedRateThrottle
: 基于作用域(URL模式)的请求速率限制。
配置方式: 可以在全局设置中配置默认限流,也可以在视图级别配置。需要在 settings.py 中配置 THROTTLE_RATES
。
“`python
settings.py (全局配置示例)
REST_FRAMEWORK = {
# …
‘DEFAULT_THROTTLE_CLASSES’: [
‘rest_framework.throttling.AnonRateThrottle’,
‘rest_framework.throttling.UserRateThrottle’
],
‘DEFAULT_THROTTLE_RATES’: {
‘anon’: ‘100/day’, # 匿名用户每天100次
‘user’: ‘1000/day’ # 认证用户每天1000次
}
}
“`
四、快速上手 Django REST Framework (示例)
让我们通过一个简单的例子来演示如何使用 DRF 构建一个基本的 API。
前提:
- 已安装 Django 和 DRF (
pip install Django djangorestframework
) - 已创建 Django 项目和应用
步骤:
-
将 ‘rest_framework’ 添加到
INSTALLED_APPS
:“`python
settings.py
INSTALLED_APPS = [
# … other apps
‘rest_framework’,
‘yourappname’, # 你的应用名称
]
“` -
创建模型 (
models.py
):“`python
yourappname/models.py
from django.db import models
from django.contrib.auth.models import Userclass Product(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
owner = models.ForeignKey(User, related_name=’products’, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)def __str__(self): return self.name
``
python manage.py makemigrations
运行和
python manage.py migrate`。 -
创建序列化器 (
serializers.py
):“`python
yourappname/serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Productclass ProductSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source=’owner.username’) # 显示所有者用户名class Meta: model = Product fields = ['id', 'name', 'description', 'price', 'owner', 'created_at']
class UserSerializer(serializers.ModelSerializer):
# 可以列出用户拥有的产品(可选)
products = serializers.PrimaryKeyRelatedField(many=True, queryset=Product.objects.all())class Meta: model = User fields = ['id', 'username', 'products']
“`
-
创建视图集 (
views.py
):“`python
yourappname/views.py
from rest_framework import viewsets
from rest_framework import permissions # 导入权限模块
from django.contrib.auth.models import User
from .models import Product
from .serializers import ProductSerializer, UserSerializer
from .permissions import IsOwnerOrReadOnly # 我们将创建一个自定义权限类class ProductViewSet(viewsets.ModelViewSet):
“””
允许用户查看、编辑产品的 API endpoint
“””
queryset = Product.objects.all().order_by(‘-created_at’)
serializer_class = ProductSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly] # 需要认证或只读,且必须是所有者才能编辑/删除# 在保存产品时,将请求用户设置为产品的owner def perform_create(self, serializer): serializer.save(owner=self.request.user)
class UserViewSet(viewsets.ReadOnlyModelViewSet):
“””
允许用户查看用户的 API endpoint
“””
queryset = User.objects.all()
serializer_class = UserSerializer
“` -
创建自定义权限类 (
permissions.py
):
“`python
# yourappname/permissions.py
from rest_framework import permissionsclass IsOwnerOrReadOnly(permissions.BasePermission):
“””
自定义权限:只允许对象的所有者编辑和删除。
“””
def has_object_permission(self, request, view, obj):
# 读取权限总是允许任何请求,
# 所以我们总是允许 GET, HEAD 或 OPTIONS 请求。
if request.method in permissions.SAFE_METHODS:
return True# 写权限只授予对象的所有者。 return obj.owner == request.user
“`
-
配置 URL 路由 (
urls.py
):“`python
yourappname/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views创建一个路由器并注册我们的视图集
router = DefaultRouter()
router.register(r’products’, views.ProductViewSet)
router.register(r’users’, views.UserViewSet)API URL 现在由路由器自动确定
urlpatterns = [
path(”, include(router.urls)),
# 还可以添加登录/注销的API endpoint,DRF提供了现成的
path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)),
]
“`“`python
yourproject/urls.py (项目主urls.py)
from django.contrib import admin
from django.urls import path, includeurlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘yourappname.urls’)), # 将应用URL包含在/api/路径下
]
“` -
运行开发服务器:
python manage.py runserver
现在,你可以通过浏览器访问 http://127.0.0.1:8000/api/
。如果使用了 DefaultRouter
且 rest_framework
在 INSTALLED_APPS
中,你将看到 DRF 提供的非常方便的浏览器化 API 界面。你可以通过这个界面查看 /api/products/
和 /api/users/
接口,进行 GET 请求。
要进行 POST, PUT, DELETE 等写操作,你需要:
- 创建用户:
python manage.py createsuperuser
或通过 Django Admin。 - 登录: 访问
http://127.0.0.1:8000/api-auth/login/
进行登录,或者在浏览器化 API 页面右上角点击 “Login”。登录后,你就可以在浏览器化 API 中看到 POST/PUT/DELETE 表单了。 - 如果你使用客户端(如 Postman 或前端应用)访问,需要根据你配置的认证方式(例如 TokenAuthentication)在请求头中携带认证信息。
这个例子展示了如何使用 ModelViewSet
和 DefaultRouter
在 DRF 中快速构建一个包含 CRUD 功能的 API 接口,并集成了权限控制。
五、DRF 的更多强大功能
除了上述核心组件,DRF 还提供了许多其他实用的功能:
- Filtering (过滤): 可以轻松地根据查询参数过滤查询集(例如
/products/?owner__username=admin
)。DRF 提供了SearchFilter
,OrderingFilter
,并可以与第三方库django-filter
深度集成,实现更复杂的过滤逻辑。 - Ordering (排序): 可以通过查询参数指定排序字段(例如
/products/?ordering=-created_at
)。 - Versioning (版本控制): 提供了多种 API 版本控制策略,如 URL 版本控制、头部版本控制等。
- Customizable Request/Response objects: DRF 封装了 Django 的 HttpRequest 和 HttpResponse,提供了更适合 API 开发的
Request
和Response
对象。 - Testing Tools: DRF 提供了用于测试 API 的客户端工具,简化了测试编写。
- Documentation Generation: 虽然 DRF 本身不直接生成完整的 API 文档,但它可以与第三方库(如
drf-yasg
,coreapi
,openapi-schema-generator
)配合,基于你的 Serializers, Views, ViewSets 自动生成 Swagger/OpenAPI 格式的文档。
六、为什么说 DRF 是 Django API 开发的利器?
- 提高开发效率: 通过 Serializers, Generic Views, ViewSets, Routers,DRF 极大地减少了样板代码的编写,让开发者能更快地构建功能完善的 API。
- 提供标准化方案: 它为 API 的数据处理、请求响应、认证权限等提供了统一的、规范的框架和流程,有助于提升代码质量和可维护性。
- 功能强大且灵活: DRF 提供了几乎所有构建现代 API 所需的功能(认证、权限、限流、分页、过滤、排序等),同时其组件化的设计使得各个部分都可以被继承和重写,以满足特定的定制需求。
- 与 Django 无缝集成: DRF 完全基于 Django,可以轻松地利用 Django 的 ORM、用户认证系统、Admin 后台等现有功能。
- 优秀的浏览器化 API: 这个特性对于开发和调试 API 来说非常方便,可以直接在浏览器中查看 API 接口,发送各种类型的请求,并查看响应。
- 活跃的社区和完善的文档: DRF 拥有庞大的用户群体和活跃的社区,遇到问题容易找到解决方案。官方文档也非常详细和清晰。
七、总结
Django REST Framework 是一个构建在 Django 之上的、用于开发 Web API 的强大而灵活的工具包。它通过引入 Serializers, Views, ViewSets, Routers 等核心概念和丰富的内置功能,极大地简化了 API 开发的复杂性,提高了开发效率,并促进了 API 的标准化。
无论是开发一个简单的内部 API,还是构建一个复杂的公共 API 服务,DRF 都能为你提供坚实的基础和强大的支持。对于 Django 开发者来说,掌握 DRF 几乎是构建现代 Web 应用不可或缺的技能。
通过本文的介绍,希望你对 DRF 有了一个全面而深入的了解,并能够开始使用它来构建你自己的 API 项目。记住,最好的学习方式是实践,尝试使用 DRF 实现不同的 API 需求,你会越来越体会到它的强大之处。