Django Rest Framework (DRF) 入门指南:构建强大而高效的 Web API
前言
在现代 Web 开发中,API(应用程序接口)扮演着核心角色。无论是为前端单页应用(SPA)、移动应用、物联网设备还是与其他服务进行数据交换,构建健壮、高效且易于维护的 Web API 都是必不可少的。Django 作为一款“会飞”的 Python Web 框架,以其高效、安全和可扩展性而闻名。然而,原生的 Django 更侧重于传统的服务器渲染模式(通过模板),直接用于构建 RESTful API 则显得有些繁琐。
正是在这种背景下,Django Rest Framework (DRF) 应运而生。DRF 是一个强大而灵活的工具包,用于快速构建 RESTful API。它构建在 Django 之上,充分利用了 Django 的各项优势,并提供了构建 API 所需的几乎所有功能,极大地简化了开发流程。
本篇文章将作为一份详细的入门指南,带您了解 DRF 的核心概念、安装配置以及如何通过一个简单的示例来构建您的第一个 API。无论您是刚接触 API 开发,还是希望提升 Django 项目的 API 构建效率,本文都将为您提供扎实的基础。
为什么选择 Django Rest Framework?
在深入学习之前,我们先了解一下 DRF 的主要优势:
- 强大的序列化器 (Serializers): 轻松处理数据的序列化(将 Django 模型对象等复杂数据类型转换为 JSON、XML 等易于传输的格式)和反序列化(将接收到的数据解析为 Python 对象并进行校验)。
- 灵活的视图 (Views): 提供了基于函数和类的多种视图类型,特别是一套强大的基于类的通用视图(Generic Views)和视图集(ViewSets),极大地减少了代码量。
- 自动生成的 API 可视化界面 (Browsable API): 开发者友好的界面,方便开发者在浏览器中直接测试 API,查看请求和响应,无需额外的 API 测试工具(如 Postman)。
- 内置认证和权限机制: 提供了多种开箱即用的认证(Authentication)和权限(Permissions)方案,保障 API 安全。
- 丰富的插件和扩展: 支持过滤(Filtering)、分页(Pagination)、版本控制(Versioning)等多种功能,且易于扩展。
- 广泛的社区支持和详细的文档: 作为 Django 生态系统中最流行的 API 框架,DRF 拥有庞大的用户群体和完善的官方文档。
总而言之,DRF 让您能够专注于业务逻辑的实现,而将 API 构建中的诸多重复性工作交给框架处理。
前提条件
在开始学习 DRF 之前,您需要:
- 熟悉 Python 编程语言。
- 对 Django 框架有基础了解,包括:
- 创建 Django 项目和应用 (app)。
- 定义模型 (Models) 并进行数据库迁移 (Migrations)。
- 了解 Django 的 URL 配置 (
urls.py
)。 - 对 Django 的视图 (Views) 有基本概念。
- 安装 Python 和 pip。
安装与配置
安装 DRF 非常简单,使用 pip 即可:
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’,
‘rest_framework’, # 添加这一行
# … 你的应用
]
… 其他设置
可选:配置 DRF 的默认设置 (此处为示例,非必须)
REST_FRAMEWORK = {
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’,
]
}
“`
这样,DRF 就成功集成到您的 Django 项目中了。
DRF 核心概念解析
DRF 的强大之处在于它对 API 开发流程的抽象和组件化。理解以下核心概念是掌握 DRF 的关键:
1. Serializers (序列化器)
- 作用: Serializers 是 DRF 中用于处理数据格式转换和数据验证的核心组件。
- 序列化 (Serialization): 将复杂的 Python 数据类型(如 Django 模型对象、QuerySet)转换为可以轻松传输的格式,最常见的是 JSON。
- 反序列化 (Deserialization): 将接收到的原始数据(通常是请求体中的 JSON)解析为 Python 数据类型,并对数据进行有效性验证。
- 工作流程:
- 当您需要从数据库中取出数据并通过 API 返回时,您会用 Serializer 将模型对象转换为字典,然后 DRF 会将字典渲染成 JSON 字符串作为响应。
- 当您接收到客户端发送的数据(如创建或更新资源)时,您会用 Serializer 将接收到的原始数据(通常是
request.data
)解析,并通过调用is_valid()
方法进行验证。验证通过后,可以通过serializer.save()
方法将数据保存到数据库(如果使用ModelSerializer
)。
- 类型:
Serializer
: 基础序列化器,用于处理任意数据结构,需要手动定义字段。ModelSerializer
: 最常用的序列化器,直接与 Django 模型关联。它可以根据模型自动生成字段,并且包含了create()
和update()
方法,使得保存数据到数据库变得非常便捷。
示例 (serializers.py):
假设我们有一个简单的 Product
模型:
“`python
models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
“`
对应的 ModelSerializer
可以这样写:
“`python
serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ‘all‘ # 或指定特定字段,如: (‘id’, ‘name’, ‘price’)
# exclude = (‘created_at’,) # 或者排除某些字段
``
fields = ‘all‘表示序列化器将包含模型的所有字段。您也可以使用一个元组来指定需要包含的字段,或者使用
exclude` 来指定需要排除的字段。
2. Views (视图)
- 作用: DRF 的视图负责处理 API 请求的逻辑,与 Django 的视图类似,但 DRF 的视图提供了更多处理 API 请求(如内容协商、请求解析、响应渲染)的便利功能。
- 类型:
APIView
: DRF 提供的最基本的类视图。它扩展了 Django 的View
类,并添加了对 DRF 的 Request/Response 对象、认证、权限、限流等特性的支持。您需要在APIView
子类中定义get()
,post()
,put()
,delete()
等方法来处理不同的 HTTP 方法。GenericAPIView
: 继承自APIView
,并增加了处理常见列表和详情操作所需的属性和方法,如queryset
,serializer_class
,lookup_field
等。它通常与 Mixins(混入类)结合使用。- Mixins (混入类): DRF 提供了一系列 Mixin 类,用于提供常见的视图行为,如
ListModelMixin
,CreateModelMixin
,RetrieveModelMixin
,UpdateModelMixin
,DestroyModelMixin
等。将GenericAPIView
与这些 Mixins 组合,可以快速构建出执行特定操作的视图类。 - ViewSets (视图集): DRF 中最强大的视图类型。一个 ViewSet 将一组相关的视图逻辑(如列表、详情、创建、更新、删除)组织在一起,对应于一个资源的多种操作。它们通常继承自
ViewSet
或ModelViewSet
。ViewSet
: 基础视图集,类似于APIView
,但将逻辑组织在list()
,retrieve()
,create()
,update()
,partial_update()
,destroy()
等方法中。需要手动定义路由。ModelViewSet
: 最常用的视图集,继承自GenericViewSet
并混入了所有常用的 Mixins (ListModelMixin
,CreateModelMixin
,RetrieveModelMixin
,UpdateModelMixin
,DestroyModelMixin
)。它直接关联一个模型,提供了完整的 CRUD(创建、读取、更新、删除)操作,并且可以非常方便地通过 Routers 自动生成 URL。
示例 (views.py):
使用 ModelViewSet
来处理 Product 的 CRUD 操作是最常见和简洁的方式:
“`python
views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly # 示例权限
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 # 指定序列化器
# permission_classes = [IsAuthenticatedOrReadOnly] # 示例:配置权限
``
ModelViewSet自动提供了
/products/(GET list, POST create) 和
/products/{id}/` (GET retrieve, PUT update, PATCH partial_update, DELETE destroy) 的逻辑实现,大大减少了样板代码。
3. Routers (路由)
- 作用: DRF 的 Routers 用于自动生成 ViewSet 的 URL 配置。当使用 ViewSet 时,您通常不需要手动编写 URL 模式,而是使用 Router 来注册 ViewSet,Router 会根据 ViewSet 提供的方法自动生成对应的 URL 路径。
- 类型:
DefaultRouter
: 提供标准的路由风格,包含列表视图/resource/
和详情视图/resource/{pk}/
,并自动生成根 API 视图(显示所有注册的 ViewSet)和格式后缀模式。SimpleRouter
: 提供一个更简单的路由风格,不包含根 API 视图和格式后缀模式。
示例 (urls.py – app 级别):
“`python
yourapp/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet
创建一个 Router 实例
router = DefaultRouter()
注册 ViewSet。第一个参数是 URL 前缀,第二个参数是 ViewSet 类
router.register(r’products’, ProductViewSet)
URL 配置中包含 Router 生成的 URL
urlpatterns = [
path(”, include(router.urls)),
# 可以在这里添加其他非 ViewSet 的 URL
# path(‘some-other-api/’, SomeOtherAPIView.as_view()),
]
“`
示例 (urls.py – project 级别):
“`python
yourproject/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘yourapp.urls’)), # 将应用的 URL 包含在 /api/ 路径下
]
``
/api/products/
通过这种方式,访问会被路由到
ProductViewSet的
list()或
create()方法,访问
/api/products/1/会被路由到
ProductViewSet的
retrieve(),
update(),
partial_update(),
destroy()` 方法(取决于请求方法)。
4. Requests & Responses (请求与响应)
Request
对象: DRF 扩展了 Django 的HttpRequest
对象,提供了更灵活的请求处理功能。关键属性包括:request.data
: 处理解析后的请求体数据,支持多种媒体类型(如 JSON, 表单数据),不像 Django 原生的request.POST
或request.body
需要手动解析。request.query_params
: 处理 URL 查询参数,类似于 Django 的request.GET
。request.user
,request.auth
: 认证相关信息。
Response
对象: DRF 提供的Response
对象可以根据客户端请求头中的Accept
字段自动选择合适的渲染器(Renderer)来格式化响应数据。您只需要将 Python 数据(如字典、列表)传递给Response
对象,DRF 会将其渲染为 JSON、HTML(用于可浏览 API)等格式。
“`python
示例 (在 APIView 中使用 Request 和 Response)
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class ExampleView(APIView):
def get(self, request, format=None):
data = {‘message’: ‘Hello, DRF!’}
return Response(data, status=status.HTTP_200_OK)
def post(self, request, format=None):
# request.data 自动解析请求体
received_data = request.data
# ... 处理数据 ...
return Response({'received': received_data}, status=status.HTTP_201_CREATED)
“`
5. Authentication & Permissions (认证与权限)
- 认证 (Authentication): 确定请求的发送者是谁。DRF 提供了多种认证方式,如:
SessionAuthentication
:基于 Django 会话(适合与 Django 后台管理或服务器渲染的前端配合)。TokenAuthentication
:基于 token(适合 SPA 或移动应用)。BasicAuthentication
:基本的用户名密码认证。
- 权限 (Permissions): 确定请求发送者是否允许执行某个操作(例如,只有管理员用户才能删除产品)。DRF 提供了多种权限类,如:
AllowAny
:允许所有用户访问(默认)。IsAuthenticated
:只允许认证用户访问。IsAdminUser
:只允许管理员用户访问。IsAuthenticatedOrReadOnly
:认证用户可以完全访问,未认证用户只能读取。- 您也可以自定义权限类。
可以在 settings.py
中设置全局的认证和权限类,也可以在视图中通过 authentication_classes
和 permission_classes
属性来为特定的视图或视图集配置。
“`python
settings.py (全局设置示例)
REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.SessionAuthentication’,
‘rest_framework.authentication.TokenAuthentication’,
],
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’
]
}
views.py (视图级别设置示例)
from rest_framework.permissions import IsAdminUser
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
permission_classes = [IsAdminUser] # 只有管理员才能访问这个 ViewSet
“`
实践:构建一个简单的产品 API
现在,我们将以上概念结合起来,创建一个简单的产品 API,实现产品的列表、创建、详情、更新和删除功能。
1. 创建 Django 项目和应用
如果您还没有项目,先创建一个:
bash
django-admin startproject myapiapp
cd myapiapp
python manage.py startapp products
将 'products'
和 'rest_framework'
添加到 myapiapp/settings.py
的 INSTALLED_APPS
中。
2. 定义 Model
在 products/models.py
中定义 Product
模型(如上所示)。
“`python
products/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
“`
运行数据库迁移:
bash
python manage.py makemigrations products
python manage.py migrate
3. 创建 Serializer
在 products/serializers.py
中创建 ProductSerializer
:
“`python
products/serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ‘all‘ # 或者指定需要的字段
“`
4. 创建 ViewSet
在 products/views.py
中创建 ProductViewSet
:
“`python
products/views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all().order_by(‘-created_at’)
serializer_class = ProductSerializer
“`
5. 配置 URL
在 products/urls.py
中使用 Router 配置 URL:
“`python
products/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet
router = DefaultRouter()
router.register(r’products’, ProductViewSet)
urlpatterns = [
path(”, include(router.urls)),
]
“`
在项目级别的 myapiapp/urls.py
中包含应用的 URL:
“`python
myapiapp/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘products.urls’)), # 将 products 的 URL 包含在 /api/ 路径下
]
“`
6. 运行服务器并测试
运行开发服务器:
bash
python manage.py runserver
打开浏览器,访问 http://127.0.0.1:8000/api/products/
。您将看到 DRF 提供的可浏览 API (Browsable API) 界面。
- GET
http://127.0.0.1:8000/api/products/
: 查看产品列表。界面下方有表单可以 POST 创建新产品。 - POST
http://127.0.0.1:8000/api/products/
: 创建新产品(通过表单或发送 JSON)。 - 访问某个产品的详情页,例如
http://127.0.0.1:8000/api/products/1/
(如果存在产品 ID 为 1 的话): 查看单个产品详情。该页面也提供了 PUT, PATCH, DELETE 的表单。
可浏览 API 是一个强大的工具,它不仅方便测试,也作为 API 文档的一部分,让其他开发者能够直观地了解 API 的结构和可用操作。
恭喜!您已经成功使用 DRF 构建了一个简单的 RESTful API,实现了对产品资源的完整 CRUD 操作。
进一步探索
本指南仅是 DRF 的冰山一角。在实际开发中,您还需要掌握更多高级特性:
- 认证 (Authentication): 实现基于 Token 或 OAuth2 的认证。
- 权限 (Permissions): 定义更精细的对象级权限控制。
- 过滤 (Filtering): 允许客户端根据字段值过滤资源列表(如查询价格低于 100 的产品)。DRF 提供了
django-filter
集成。 - 分页 (Pagination): 控制列表 API 的响应大小,避免一次返回过多数据。
- 限流 (Throttling): 限制用户或 IP 在一定时间内访问 API 的频率。
- 版本控制 (Versioning): 在 API 演进时保持向后兼容性。
- 自定义 Serializers 字段和验证规则。
- 使用函数式视图 (
@api_view
) 处理简单场景。 - API 文档生成: 集成 Swagger/OpenAPI 生成交互式 API 文档。
- 测试: 使用 DRF 的
APIClient
进行 API 接口测试。
DRF 的官方文档是学习这些高级特性的最佳资源。通过实践和查阅文档,您将能够构建出功能强大、安全可靠的 Web API。
总结
Django Rest Framework 是构建 RESTful API 的首选框架之一,它基于 Django,提供了丰富的功能和工具,极大地提高了开发效率。通过理解 Serializers, Views ( khususnya ModelViewSet), Routers 这些核心概念,并结合可浏览 API 进行实践,您可以快速入门并开始构建自己的 API 项目。
从简单的 CRUD API 到复杂的企业级服务,DRF 都能提供强大的支持。希望这篇详细的入门指南能帮助您迈出 DRF 学习的第一步。祝您编码愉快!