Django REST Framework 入门教程:零基础快速上手
你好!如果你已经对 Python 和 Django 有了基本的了解,并且想构建一个强大的 Web API,那么你来对地方了。Django REST Framework (DRF) 是一个灵活且强大的工具包,可以让你快速构建出符合 RESTful 规范的 Web API。
本教程将从零开始,一步步带你了解 DRF 的核心概念和使用方法,最终构建一个简单的 API 应用。
1. 什么是 RESTful API?为什么选择 Django REST Framework?
1.1 什么是 RESTful API?
REST (Representational State Transfer) 是一种架构风格,用于设计网络应用程序。RESTful API 是遵循 REST 原则设计的 API。它的核心思想是将服务器上的资源(Resource)通过 URI(统一资源标识符)暴露出来,客户端通过 HTTP 方法(如 GET, POST, PUT, DELETE)对这些资源进行操作。
简单来说,一个 RESTful API 就像是一个网站,但它不是为人类浏览器设计的,而是为程序设计的。通过发送特定的 HTTP 请求,程序可以获取或修改服务器上的数据。
REST 的主要原则:
- 无状态 (Stateless): 服务器不存储客户端的状态信息。每个请求都包含处理该请求所需的所有信息。
- 统一接口 (Uniform Interface): 客户端和服务器之间的通信方式是统一的。主要体现在使用标准的 HTTP 方法和资源标识。
- 可缓存 (Cacheable): 客户端可以缓存服务器的响应,以提高性能。
- 分层系统 (Layered System): 客户端无法判断它是否直接连接到最终服务器,或者中间是否有代理、网关等。
- 按需代码 (Code on Demand – Optional): 服务器可以临时扩展或定制客户端的功能,通过下载并执行代码(如 JavaScript)。这在 API 场景中较少使用。
- 客户端-服务器分离 (Client-Server Separation): 客户端和服务器是相互独立的,它们只通过统一的接口进行通信。
1.2 为什么选择 Django REST Framework?
Django 是一个非常流行的 Python Web 框架,以其“DRY”(Don’t Repeat Yourself)原则和快速开发能力而闻名。DRF 是为 Django 设计的,它充分利用了 Django 的优点,并为其构建 API 提供了大量便利:
- 易于使用和上手: 如果你熟悉 Django,学习 DRF 会非常快。它提供了许多类和工具,可以帮你快速构建 API。
- 强大的序列化器 (Serializers): DRF 的序列化器可以轻松地将 Django 的模型对象转换为 API 可以理解的数据格式(如 JSON),反之亦然(数据验证和模型保存)。
- 灵活的视图 (Views): DRF 提供了多种视图类,从简单的
APIView
到强大的通用视图 (generics
) 和视图集 (ViewSets
),可以处理各种 API 逻辑。 - 自带认证和权限系统: DRF 集成了灵活的认证和权限机制,可以轻松控制哪些用户可以访问哪些资源。
- 浏览器友好的 API: DRF 自带的 Web 浏览器可浏览 API 功能非常强大,它为你提供了方便的调试和测试界面。
- 丰富的文档和社区支持: DRF 拥有完善的官方文档和庞大的社区,遇到问题很容易找到解决方案。
简而言之,如果你用 Django 构建 Web 应用,并且需要为其提供 API 接口(可能是供移动 App、JavaScript 前端或者其他服务调用),DRF 是你的首选。
2. 准备工作
在开始之前,请确保你已经具备以下基础:
- Python 环境(建议使用 Python 3.6+)
- pip 包管理器
- 虚拟环境的使用(强烈推荐,隔离项目依赖)
- Django 的基本知识(如何创建项目、应用、模型、进行数据库迁移等)
如果你还不熟悉 Django 的基本操作,建议先学习一下 Django 的官方教程或相关入门资料。
2.1 设置虚拟环境和安装 Django/DRF
首先,创建一个新的虚拟环境并激活它:
“`bash
对于 macOS/Linux
python -m venv myapi_venv
source myapi_venv/bin/activate
对于 Windows
python -m venv myapi_venv
myapi_venv\Scripts\activate
“`
激活虚拟环境后,安装 Django 和 Django REST Framework:
bash
pip install django djangorestframework
2.2 创建 Django 项目和应用
接下来,创建一个新的 Django 项目和应用:
“`bash
在 myapi_venv 目录外创建项目,或者在你希望存放项目的目录
django-admin startproject myapi_project . # 注意 ‘.’ 表示在当前目录创建项目
cd myapi_project # 进入项目根目录
创建一个应用
python manage.py startapp notes_api
“`
2.3 配置项目
打开项目根目录下的 settings.py
文件,将新创建的应用 'notes_api'
和 'rest_framework'
添加到 INSTALLED_APPS
中:
“`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’,
‘rest_framework’, # 添加这一行
‘notes_api’, # 添加这一行
]
… 其他设置
“`
现在,你可以运行初始的数据库迁移了:
bash
python manage.py migrate
至此,你的 DRF 开发环境就搭建好了!
3. 构建你的第一个 API:创建一个简单的笔记应用
我们将构建一个简单的笔记 API,它允许我们创建、查看、更新和删除笔记。
3.1 定义数据模型 (Model)
首先,在 notes_api/models.py
中定义一个简单的 Note
模型:
“`python
notes_api/models.py
from django.db import models
class Note(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
“`
定义完模型后,进行数据库迁移:
bash
python manage.py makemigrations notes_api
python manage.py migrate
3.2 序列化器 (Serializer)
序列化器是 DRF 的核心概念之一。它的主要作用是将复杂的模型对象(Django Model Instances)转换为可传输的数据格式(如 JSON),以及将传入的数据(如 JSON)反序列化为模型对象,并进行数据验证。
对于与模型紧密相关的 API,DRF 提供了 ModelSerializer
,它可以根据模型自动生成序列化器的字段,极大地简化了代码。
在 notes_api
应用目录下创建一个新的文件 serializers.py
:
“`python
notes_api/serializers.py
from rest_framework import serializers
from .models import Note
class NoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = [‘id’, ‘title’, ‘content’, ‘created_at’] # 指定需要序列化的字段
# 或者使用 fields = ‘all‘ 来包含模型所有字段
# 如果要排除某些字段,可以使用 exclude = [‘field_name’]
“`
在这个 NoteSerializer
中:
- 我们继承自
serializers.ModelSerializer
。 - 在内部的
Meta
类中,我们指定了它对应的模型是Note
(model = Note
)。 fields
属性列出了我们希望在 API 输出中包含的模型字段。'id'
字段通常是自动生成的,但为了在 API 中显示和使用,我们将其包含进来。
序列化器现在可以将 Note
对象的列表或单个对象转换为字典列表或字典,也可以接收字典数据并尝试创建或更新 Note
对象。
3.3 视图 (Views)
视图处理传入的请求,与序列化器和模型交互,并返回响应。DRF 提供了多种视图类,它们提供了不同级别的抽象。我们将从最基础的 APIView
开始,然后介绍更方便的通用视图和视图集。
3.3.1 使用 APIView
APIView
是 DRF 提供的最基本的视图类,它继承自 Django 的 View
类,并添加了对 DRF 特性的支持,如请求解析、响应渲染、认证、权限等。你需要手动实现 HTTP 方法对应的处理函数(如 get
, post
, put
, delete
)。
打开 notes_api/views.py
,添加以下代码:
“`python
notes_api/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
from .models import Note
from .serializers import NoteSerializer
处理 /notes/ 请求 (GET 获取列表, POST 创建)
class NoteListCreateAPIView(APIView):
“””
列出所有笔记或创建一篇新笔记
“””
def get(self, request, format=None):
“””
获取所有笔记列表
“””
notes = Note.objects.all()
serializer = NoteSerializer(notes, many=True) # many=True 表示序列化一个查询集
return Response(serializer.data)
def post(self, request, format=None):
"""
创建一篇新笔记
"""
serializer = NoteSerializer(data=request.data) # request.data 包含解析后的请求体数据
if serializer.is_valid(): # 验证数据是否有效
serializer.save() # 保存到数据库,会调用 serializer 的 create() 方法
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
处理 /notes// 请求 (GET 获取详情, PUT 更新, DELETE 删除)
class NoteDetailAPIView(APIView):
“””
获取、更新或删除一篇笔记
“””
def get_object(self, pk):
“””
根据主键获取 Note 对象,如果不存在则返回 404
“””
try:
return Note.objects.get(pk=pk)
except Note.DoesNotExist:
raise Http404 # DRF 会将 Django 的 Http404 转换为 DRF 的 Response(status=404)
def get(self, request, pk, format=None):
"""
获取单篇笔记详情
"""
note = self.get_object(pk)
serializer = NoteSerializer(note)
return Response(serializer.data)
def put(self, request, pk, format=None):
"""
更新单篇笔记
"""
note = self.get_object(pk)
serializer = NoteSerializer(note, data=request.data) # 传入实例和新的数据
if serializer.is_valid():
serializer.save() # 保存更新,会调用 serializer 的 update() 方法
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
"""
删除单篇笔记
"""
note = self.get_object(pk)
note.delete()
return Response(status=status.HTTP_204_NO_CONTENT) # 删除成功通常返回 204
“`
代码解释:
APIView
子类为每个 HTTP 方法定义了对应的小写方法(get
,post
,put
,delete
)。request.data
是 DRF 在解析请求体后得到的数据(如果是 JSON 请求,它就是一个字典)。Response
是 DRF 提供的响应对象,它可以接受序列化后的数据,并自动根据请求的Accept
头渲染成合适的格式(如 JSON)。status
参数用来设置 HTTP 状态码。serializer.is_valid()
运行序列化器中定义的数据验证规则。serializer.save()
根据验证后的数据创建或更新模型实例。如果创建时传入了instance
参数,它会调用序列化器的update()
方法;否则调用create()
方法。get_object
是一个辅助方法,用于根据主键获取模型实例,并处理不存在的情况。DRF 会将 Django 的Http404
异常捕获并转换为一个合适的 404 响应。
3.4 配置 URL
现在需要将这些视图映射到 URL。在 myapi_project/urls.py
中包含 notes_api
的 URL 配置。
首先,创建 notes_api/urls.py
文件:
“`python
notes_api/urls.py
from django.urls import path
from .views import NoteListCreateAPIView, NoteDetailAPIView
urlpatterns = [
path(‘notes/’, NoteListCreateAPIView.as_view(), name=’note-list-create’),
path(‘notes/
]
“`
然后,在项目根目录的 myapi_project/urls.py
中包含它:
“`python
myapi_project/urls.py
from django.contrib import admin
from django.urls import path, include # 导入 include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘notes_api.urls’)), # 添加这一行,将 notes_api 的 URL 包含在 /api/ 路径下
]
“`
现在,我们有了两个 API 端点:
/api/notes/
: 对应NoteListCreateAPIView
,处理 GET (获取列表) 和 POST (创建) 请求。/api/notes/<int:pk>/
: 对应NoteDetailAPIView
,处理 GET (获取详情), PUT (更新), DELETE (删除) 请求。
3.5 测试你的 API (使用浏览器可浏览 API)
DRF 最酷的功能之一是它提供了自动生成的浏览器可浏览 API。当你用浏览器访问 API 端点时,DRF 会渲染一个用户界面,让你方便地查看、测试和调试 API。
运行开发服务器:
bash
python manage.py runserver
打开浏览器,访问 http://127.0.0.1:8000/api/notes/
。
你应该会看到一个漂亮的页面,显示当前没有笔记(因为数据库是空的)。你可以通过页面下方的表单提交数据(Title 和 Content)来创建一篇新笔记。
尝试以下操作:
- GET /api/notes/: 在浏览器中访问,查看笔记列表。
- POST /api/notes/: 在浏览器页面下方的表单中填写 Title 和 Content,然后点击 POST 按钮创建一篇笔记。你会看到新创建的笔记数据和 201 Created 状态码。
- GET /api/notes/
/ : 在浏览器中访问刚才创建的笔记的 URL (例如http://127.0.0.1:8000/api/notes/1/
,如果 id 是 1),查看单篇笔记详情。 - PUT /api/notes/
/ : 在单篇笔记详情页面,你会看到一个用于更新的表单。修改数据后点击 PUT 按钮更新。 - DELETE /api/notes/
/ : 在单篇笔记详情页面,点击 DELETE 按钮删除笔记。你会收到 204 No Content 响应,再次访问列表或详情会发现该笔记已不存在。
恭喜!你已经成功构建了你的第一个 DRF API,并使用浏览器可浏览 API 进行了测试。使用 APIView
可以让你对请求/响应的处理有完全的控制,但在实际开发中,对于标准的 CRUD 操作,DRF 提供了更高级的抽象。
4. 进一步简化:通用视图 (Generic API Views)
DRF 认识到许多 API 视图遵循相似的模式(如列出、创建、检索、更新、删除模型实例)。为了减少重复代码,它提供了一组通用的 API 视图。这些视图基于 APIView
构建,并混合 (Mixins
) 了常用的行为。
我们将用通用视图重写上面的 APIView
示例。
打开 notes_api/views.py
,使用以下代码替换之前的内容:
“`python
notes_api/views.py (使用通用视图)
from rest_framework import generics # 导入 generics
from .models import Note
from .serializers import NoteSerializer
处理 /notes/ 请求 (GET 获取列表, POST 创建)
class NoteListCreateAPIView(generics.ListCreateAPIView):
“””
列出所有笔记或创建一篇新笔记(使用通用视图)
“””
queryset = Note.objects.all() # 指定查询集
serializer_class = NoteSerializer # 指定序列化器
处理 /notes// 请求 (GET 获取详情, PUT 更新, DELETE 删除)
class NoteDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
“””
获取、更新或删除一篇笔记(使用通用视图)
“””
queryset = Note.objects.all() # 指定查询集,注意这里也需要,用于查找对象
serializer_class = NoteSerializer # 指定序列化器
“`
是不是简洁了很多?
代码解释:
generics.ListCreateAPIView
:这个类组合了ListModelMixin
和CreateModelMixin
。ListModelMixin
提供了处理 GET 请求(用于列出多个实例)的逻辑。CreateModelMixin
提供了处理 POST 请求(用于创建新实例)的逻辑。
generics.RetrieveUpdateDestroyAPIView
:这个类组合了RetrieveModelMixin
,UpdateModelMixin
, 和DestroyModelMixin
。RetrieveModelMixin
提供了处理 GET 请求(用于获取单个实例详情)的逻辑。UpdateModelMixin
提供了处理 PUT/PATCH 请求(用于更新单个实例)的逻辑。DestroyModelMixin
提供了处理 DELETE 请求(用于删除单个实例)的逻辑。
- 通过简单地设置
queryset
属性(指定要查询的数据集)和serializer_class
属性(指定要使用的序列化器),这些通用视图就能够自动处理相应的 HTTP 请求并执行 CRUD 操作。
URL 配置 (notes_api/urls.py
) 保持不变,因为视图类的名字没有变。
再次运行服务器,访问 http://127.0.0.1:8000/api/notes/
。你会发现 API 的功能和之前使用 APIView
实现的完全一样,但代码量大大减少了。在实际项目中,对于标准的模型 CRUD API,通用视图是首选。
5. 终极简化:视图集 (ViewSets) 和路由器 (Routers)
通用视图已经很方便了,但通常一个资源的多个操作(列表、创建、详情、更新、删除)都集中在一个地方。DRF 的视图集 (ViewSets
) 进一步将这些相关的逻辑打包到一个类中。
与 APIView
或通用视图不同,视图集不直接提供 HTTP 方法处理函数(如 .get()
, .post()
)。它们提供的是如 .list()
, .create()
, .retrieve()
, .update()
, .partial_update()
, .destroy()
等方法,这些方法对应于常见的 API 操作。
视图集通常与路由器 (Routers
) 配合使用。路由器会自动为视图集生成 URL 模式,免去了手动编写 URL 配置的麻烦。
我们将用视图集和路由器重写上面的示例。
打开 notes_api/views.py
,使用以下代码替换之前的内容:
“`python
notes_api/views.py (使用视图集)
from rest_framework import viewsets # 导入 viewsets
from .models import Note
from .serializers import NoteSerializer
使用 ModelViewSet
class NoteViewSet(viewsets.ModelViewSet):
“””
一个用于查看、编辑和删除笔记的视图集。
“””
queryset = Note.objects.all()
serializer_class = NoteSerializer
“`
这就是所有的视图代码!ModelViewSet
继承自 GenericViewSet
,并混合了 ListModelMixin
, CreateModelMixin
, RetrieveModelMixin
, UpdateModelMixin
, DestroyModelMixin
。它提供了处理所有五种标准 CRUD 操作 (.list()
, .create()
, .retrieve()
, .update()
, .destroy()
) 的方法。通过设置 queryset
和 serializer_class
,它就能自动完成所有工作。
现在,我们需要修改 URL 配置来使用路由器。
打开 notes_api/urls.py
,使用以下代码替换之前的内容:
“`python
notes_api/urls.py (使用路由器)
from rest_framework.routers import DefaultRouter # 导入 DefaultRouter
from .views import NoteViewSet
创建一个路由器实例
router = DefaultRouter()
注册视图集
第一个参数是 URL 前缀 (例如 ‘notes’)
第二个参数是视图集类
第三个参数是可选的 basename,用于生成 URL 名称 (例如 ‘note-list’)
router.register(r’notes’, NoteViewSet, basename=’note’)
router.urls 会自动生成对应的 URL pattern 列表
urlpatterns = router.urls
“`
在项目根目录的 myapi_project/urls.py
中,包含 notes_api.urls
的方式不变:
“`python
myapi_project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘notes_api.urls’)), # 保持不变
]
“`
现在,路由器 DefaultRouter
自动为 NoteViewSet
生成了以下 URL 模式:
/api/notes/
:对应NoteViewSet.list()
(GET) 和NoteViewSet.create()
(POST)/api/notes/{pk}/
:对应NoteViewSet.retrieve()
(GET),NoteViewSet.update()
(PUT),NoteViewSet.partial_update()
(PATCH),NoteViewSet.destroy()
(DELETE)
再次运行服务器,访问 http://127.0.0.1:8000/api/notes/
。你会发现 API 的功能与之前使用 APIView
或通用视图实现的完全一样。使用视图集和路由器是构建 RESTful API 的最简洁和推荐的方式,特别是当你的 API 围绕着模型资源展开时。
6. 总结与下一步
通过本教程,你应该已经掌握了 Django REST Framework 的核心概念,并成功构建了一个简单的笔记 API:
- RESTful API 的基本思想和 DRF 的优势。
- 序列化器 (Serializers) 的作用,特别是
ModelSerializer
如何将模型与 API 数据格式相互转换。 - 视图 (Views) 的不同抽象层次:
APIView
:提供了基础框架,需要手动实现 HTTP 方法处理函数。- 通用视图 (
generics
):提供了常用的 CRUD Mixins,通过设置queryset
和serializer_class
即可实现功能。 - 视图集 (
ViewSets
):将相关的 API 操作(如 list, create, retrieve, update, destroy)打包到一个类中。
- 路由器 (
Routers
) 如何与视图集配合,自动生成 URL 模式。 - 如何使用 浏览器可浏览 API 进行测试和调试。
这只是 DRF 的冰山一角。为了构建更强大、更安全的 API,你还需要学习:
- 认证 (Authentication): 如何识别谁发出了请求(例如,Token 认证,Session 认证)。
- 权限 (Permissions): 如何确定用户是否有权执行某个操作(例如,只有创建者可以删除笔记)。
- 限流 (Throttling): 如何限制用户或 IP 的请求频率,防止滥用。
- 分页 (Pagination): 如何处理大量数据,避免一次性返回所有结果。
- 过滤和搜索 (Filtering & Searching): 如何让用户通过查询参数过滤或搜索数据。
- 版本控制 (Versioning): 如何在 API 演进时保持向后兼容。
- 测试 (Testing): 如何编写自动化测试来确保 API 的正确性。
- 文档 (Documentation): 如何为 API 生成文档(例如,使用 drf-yasg 或 coreapi)。
学习这些主题将帮助你构建更加健壮和专业的 API。
下一步建议:
- 复习代码: 仔细回顾本教程中的代码,理解每个部分的意义。
- 动手实践: 尝试在你的笔记 API 中添加更多字段,或者创建一个新的应用和模型,为它构建 API。
- 阅读官方文档: DRF 的官方文档非常优秀,是深入学习的最佳资源。从序列化器、请求/响应对象、视图等核心概念开始阅读。
- 探索更多特性: 尝试实现认证、权限、分页等功能。
构建 API 是现代 Web 开发中非常重要的一部分。掌握 DRF 将为你打开通往构建各种后端服务的广阔大门。
祝你学习愉快!