I have completed the Django REST Framework tutorial. Due to the unavailability of a file writing tool, I am presenting the complete article content directly as my response.
Django REST Framework 入门教程
1. 简介:什么是 Django REST Framework?
在现代 Web 开发中,构建能够与各种客户端(如前端 Web 应用、移动应用或其他服务)交互的后端 API 变得至关重要。RESTful API 因其简单、无状态和可扩展性而成为构建这些服务的首选架构风格。
Django REST Framework (DRF) 是一个强大而灵活的工具包,用于在 Django 的基础上快速构建 Web API。它建立在 Django 现有功能之上,提供了大量开箱即用的功能,极大地简化了 API 的开发过程。
为什么选择 DRF?
- 强大的序列化器 (Serializers):DRF 的序列化器可以将复杂的数据类型(如 Django 模型实例或查询集)转换为原生 Python 数据类型,使其易于渲染为 JSON、XML 或其他内容类型。反之,它们也可以将传入的 JSON/XML 数据反序列化并验证,然后保存到模型实例中。
- 可浏览的 API (Browsable API):DRF 提供了一个美观、完全可定制的 Web 界面,让开发人员可以直接在浏览器中查看和测试 API 端点。这对于开发和调试非常有帮助。
- 认证和权限 (Authentication & Permissions):内置了多种认证方案(如 Session、Token、OAuth2)和灵活的权限系统,可以轻松控制用户对 API 的访问。
- 视图类 (View Classes):提供了基于类的视图(CBVs)和通用的可重用视图,可以处理常见的 API 模式,如列表、创建、检索、更新和删除。
- 灵活的路由 (Flexible Routing):DRF 的路由器可以自动生成 URL 模式,特别是对于
ViewSet。 - 文档和测试 (Documentation & Testing):支持 API 自动化文档生成,并提供了用于测试 API 的工具。
简而言之,如果你正在使用 Django 构建后端,并且需要对外提供一个 RESTful API,那么 Django REST Framework 几乎是你的不二之选。它能让你在保持 Django 强大功能的同时,高效地构建出高质量的 API。
2. 环境设置与项目初始化
在开始编写 API 之前,我们需要设置好开发环境,并创建一个 Django 项目和应用。
2.1 安装 Python 和虚拟环境
确保你的系统已安装 Python 3.6 或更高版本。推荐使用虚拟环境来隔离项目依赖。
“`bash
创建一个虚拟环境
python -m venv drf_env
激活虚拟环境
Windows
.\drf_env\Scripts\activate
macOS/Linux
source drf_env/bin/activate
“`
激活虚拟环境后,你会看到命令行前缀变为 (drf_env)。
2.2 安装 Django 和 Django REST Framework
在激活的虚拟环境中,安装 Django 和 Django REST Framework:
bash
pip install django djangorestframework
2.3 创建 Django 项目和应用
我们将创建一个名为 drf_tutorial_project 的项目和一个名为 blog 的应用来演示。
“`bash
创建 Django 项目
django-admin startproject drf_tutorial_project .
创建 Django 应用
python manage.py startapp blog
“`
2.4 配置 settings.py
打开 drf_tutorial_project/settings.py 文件,在 INSTALLED_APPS 列表中添加 'rest_framework' 和 'blog':
“`python
drf_tutorial_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
‘rest_framework’,
# 添加你的应用
‘blog’,
]
… 其他设置 …
“`
2.5 运行初始迁移
在项目根目录(manage.py 所在的目录)运行数据库迁移,为 Django 的内置功能创建必要的表:
bash
python manage.py migrate
至此,你的 Django 项目和 DRF 环境已成功设置。
3. 定义数据模型
我们将为 blog 应用创建一个简单的 Post 模型,代表博客文章。
3.1 创建 Post 模型
打开 blog/models.py 文件,并添加以下代码:
“`python
blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
“`
这个 Post 模型包含标题、内容和创建/更新时间戳。
3.2 生成并应用数据库迁移
保存 blog/models.py 后,需要告诉 Django 我们对模型进行了更改,并将其反映到数据库中。
首先,生成迁移文件:
bash
python manage.py makemigrations blog
你将看到类似 blog/migrations/0001_initial.py 的文件被创建。
然后,应用这些迁移到数据库:
bash
python manage.py migrate
现在,数据库中已经有了 Post 模型对应的表。
3.3 创建超级用户(可选,但推荐)
为了方便管理和初步测试,我们可以创建一个超级用户来访问 Django Admin 后台,并手动添加一些 Post 数据。
bash
python manage.py createsuperuser
按照提示输入用户名、邮箱和密码。
然后启动开发服务器:
bash
python manage.py runserver
访问 http://127.0.0.1:8000/admin/,使用你创建的超级用户登录。你还需要在 blog/admin.py 中注册 Post 模型才能在后台管理它:
“`python
blog/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
“`
重启服务器后,你就可以在 Admin 后台添加、修改 Post 对象了。
4. 序列化器 (Serializers):连接数据和 API
序列化器在 Django REST Framework 中扮演着核心角色。它们负责将复杂的 Django 模型实例转换为易于传输和呈现的 Python 原生数据类型(如字典),然后可以轻松地渲染成 JSON、XML 等格式。反之,序列化器也能将传入的结构化数据(如 JSON)验证并转换回 Django 模型实例。
4.1 创建 serializers.py
在 blog 应用目录下创建一个新文件 blog/serializers.py,并添加以下代码:
“`python
blog/serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = [‘id’, ‘title’, ‘content’, ‘created_at’, ‘updated_at’]
# 或者使用 fields = ‘all‘ 来包含模型中的所有字段
“`
4.2 ModelSerializer 详解
这里我们使用了 serializers.ModelSerializer,它是 DRF 提供的一个非常方便的类,可以自动为 Django 模型生成一系列的字段和验证器。
class Meta:: 这是ModelSerializer的内部类,用于配置序列化器的行为。model = Post: 告诉序列化器它应该与哪个 Django 模型关联。fields = [...]: 指定在序列化时应该包含模型中的哪些字段。'id'字段通常是自动生成的,并且在 API 响应中非常有用。你也可以使用fields = '__all__'来包含所有字段,或者exclude = ['field_name']来排除特定字段。
PostSerializer 现在能够:
- 将
Post模型实例转换为 JSON 格式的字典。 - 对传入的数据进行验证,确保它们符合
Post模型的字段要求。 - 在验证通过后,将数据保存为新的
Post模型实例或更新现有实例。
5. API 视图:处理 HTTP 请求
API 视图是处理传入 HTTP 请求并返回 HTTP 响应的地方。Django REST Framework 提供了多种方式来编写视图,从底层的 APIView 到功能强大的通用视图和视图集。
5.1 使用 APIView(基础)
APIView 是 DRF 提供的最基础的视图类,它比 Django 自带的 View 类提供了更多 RESTful 特性,如请求解析、响应渲染和认证/权限处理。
打开 blog/views.py 文件,并添加以下代码:
“`python
blog/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 Post
from .serializers import PostSerializer
class PostList(APIView):
“””
列出所有 Post 或创建一个新的 Post。
“””
def get(self, request, format=None):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = PostSerializer(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 PostDetail(APIView):
“””
检索、更新或删除一个 Post 实例。
“””
def get_object(self, pk):
try:
return Post.objects.get(pk=pk)
except Post.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
post = self.get_object(pk)
serializer = PostSerializer(post)
return Response(serializer.data)
def put(self, request, pk, format=None):
post = self.get_object(pk)
serializer = PostSerializer(post, data=request.data)
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):
post = self.get_object(pk)
post.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
“`
这段代码实现了:
* PostList: 处理 GET 请求(获取所有文章)和 POST 请求(创建新文章)。
* PostDetail: 处理 GET(获取单篇文章)、PUT(更新文章)和 DELETE(删除文章)请求。
5.2 使用通用视图 generics(推荐)
DRF 提供了许多通用视图,它们抽象了常见的 API 行为,使代码更加简洁。对于 CRUD (创建、检索、更新、删除) 操作,通用视图是理想选择。
我们可以用通用视图重写上面的 PostList 和 PostDetail:
“`python
blog/views.py (替换或添加到现有代码下方)
from rest_framework import generics
… 之前的导入 …
class PostListGeneric(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
class PostDetailGeneric(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
“`
ListCreateAPIView: 提供了列出所有对象 (GET) 和创建新对象 (POST) 的功能。RetrieveUpdateDestroyAPIView: 提供了检索 (GET)、更新 (PUT/PATCH) 和删除 (DELETE) 单个对象的功能。
通过设置 queryset 和 serializer_class 属性,通用视图会自动处理大部分逻辑。
5.3 视图集 Viewsets(高级)
对于更复杂的场景,DRF 的 Viewsets 可以将一组相关的视图逻辑(如列表、详情、创建、更新、删除)组合在一个类中,并通过路由器自动生成 URL。这进一步减少了代码重复。
“`python
blog/views.py (添加,但暂时不会在 URL 中使用)
from rest_framework import viewsets
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
“`
ModelViewSet 提供了完整的 CRUD 操作,并且非常适合与 DRF 的路由器配合使用。在本教程的 URL 配置部分,我们将展示如何使用它。
6. URL 路由:将请求映射到视图
现在我们已经定义了模型、序列化器和视图,接下来需要配置 URL 路由,以便将 HTTP 请求正确地导向到相应的视图处理函数或方法。
6.1 配置应用的 urls.py
在 blog 应用目录下创建一个新文件 blog/urls.py,并添加以下代码。我们将演示两种配置方式:使用通用视图和使用视图集。
使用通用视图 (推荐)
这是最常见且推荐的方式,因为它简洁明了。
“`python
blog/urls.py
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
urlpatterns = [
path(‘posts/’, views.PostListGeneric.as_view(), name=’post-list’),
path(‘posts/
]
urlpatterns = format_suffix_patterns(urlpatterns)
“`
path('posts/', ...): 将GET请求到/posts/和POST请求到/posts/映射到PostListGeneric视图,用于获取文章列表和创建新文章。path('posts/<int:pk>/', ...): 将GET、PUT/PATCH、DELETE请求到/posts/{id}/映射到PostDetailGeneric视图,用于获取、更新和删除特定文章。format_suffix_patterns: 允许你在 URL 中使用.json或.api等后缀来指定响应的格式(例如http://127.0.0.1:8000/posts.json)。
6.2 配置项目的 urls.py
现在,我们需要将 blog 应用的 URL 包含到项目的 drf_tutorial_project/urls.py 中。
“`python
drf_tutorial_project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘blog.urls’)), # 将 ‘blog’ 应用的 URL 包含进来,并以 ‘api/’ 为前缀
]
“`
现在,你的 API 端点将以 http://127.00.1:8000/api/posts/ 和 http://127.0.0.1:8000/api/posts/{id}/ 形式访问。
6.3 使用视图集 Viewsets 和路由器 (更高级、更简洁)
如果你在 blog/views.py 中定义了 PostViewSet,那么可以使用 DRF 的路由器来自动生成 URL。这种方式特别适用于 RESTful API,它能将视图集的各种操作(列表、详情、创建、更新、删除)自动映射到对应的 URL 路径。
首先,确保 blog/views.py 中有 PostViewSet:
“`python
blog/views.py (部分内容)
…
from rest_framework import viewsets
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
“`
然后,修改 blog/urls.py 以使用路由器:
“`python
blog/urls.py (使用 ViewSet 替换之前的 urlpatterns)
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register(r’posts’, views.PostViewSet, basename=’post’) # ‘posts’ 是 URL 前缀
urlpatterns = [
path(”, include(router.urls)),
]
“`
这里:
* DefaultRouter(): 创建一个默认路由器实例。
* router.register(r'posts', views.PostViewSet, basename='post'): 注册 PostViewSet,并指定 URL 前缀为 posts。basename 用于在没有 queryset 属性时生成 URL 名称。
* path('', include(router.urls)): 将路由器自动生成的 URL 包含进来。
使用 PostViewSet 和路由器后,DRF 会自动生成以下 URL 模式:
* /posts/ (GET, POST) -> PostViewSet.list, PostViewSet.create
* /posts/{pk}/ (GET, PUT, PATCH, DELETE) -> PostViewSet.retrieve, PostViewSet.update, PostViewSet.partial_update, PostViewSet.destroy
注意:在实际项目中,你通常会选择一种 URL 路由方式。为了本教程的清晰,我们在此展示了两种,但在实践中请选择最适合你项目的方式。为了后续测试方便,我们假设你使用的是通用视图 (PostListGeneric 和 PostDetailGeneric) 的配置。
7. 测试你的 API
现在你的 API 已经搭建好了,是时候进行测试了!Django REST Framework 提供了一个非常方便的“可浏览的 API”界面,也可以通过命令行工具或专门的 API 客户端进行测试。
7.1 启动 Django 开发服务器
确保你的 Django 开发服务器正在运行。如果没有,请在项目根目录(manage.py 所在目录)中运行:
bash
python manage.py runserver
7.2 使用可浏览的 API
打开你的 Web 浏览器,访问列表 API 端点:http://127.0.0.1:8000/api/posts/。
如果一切配置正确,你将看到 Django REST Framework 提供的一个美观的 Web 界面。
- 查看列表: 页面会显示当前数据库中所有的
Post对象(如果还没有,则为空列表)。 - 创建新 Post: 在页面底部,你会看到一个表单,可以通过它
POST一个新的Post对象。输入title和content,然后点击POST按钮。如果成功,你会看到新创建的Post数据。 - 查看详情: 点击某个 Post 的
id,或者直接访问http://127.0.0.1:8000/api/posts/{post_id}/(例如http://127.0.0.1:8000/api/posts/1/),你将看到单个 Post 的详细信息。 - 更新/删除: 在详情页面,你还可以看到
PUT、PATCH和DELETE表单,用于更新或删除该 Post。
可浏览的 API 是开发和调试 API 的强大工具,因为它直观地展示了 API 的结构、请求方法和响应。
7.3 使用 curl 进行测试 (命令行)
你也可以使用 curl 这个命令行工具来测试你的 API。
-
获取所有 Post (GET):
bash
curl http://127.0.0.1:8000/api/posts/
你会得到一个 JSON 格式的 Post 列表。 -
创建一个新的 Post (POST):
bash
curl -X POST -H "Content-Type: application/json" -d '{"title": "我的第一篇 API 文章", "content": "这是通过 API 创建的一篇文章。"}' http://127.0.0.1:8000/api/posts/
-X POST: 指定 HTTP 方法为 POST。
-H "Content-Type: application/json": 告诉服务器发送的数据是 JSON 格式。
-d '...': 包含要发送的 JSON 数据。 -
获取单个 Post (GET):
bash
curl http://127.0.0.1:8000/api/posts/1/ # 替换 1 为实际的 Post ID -
更新单个 Post (PUT):
bash
curl -X PUT -H "Content-Type: application/json" -d '{"title": "更新后的标题", "content": "这是更新后的内容"}' http://127.0.0.1:8000/api/posts/1/
请注意,PUT请求通常需要发送所有字段。 -
删除单个 Post (DELETE):
bash
curl -X DELETE http://127.0.0.1:8000/api/posts/1/
成功删除后,你会收到 204 No Content 响应。
7.4 使用 Postman/Insomnia 等 API 客户端
对于更复杂的 API 测试,推荐使用专业的 API 客户端工具,如 Postman 或 Insomnia。它们提供图形界面来构建和发送请求,管理认证,以及查看响应,功能比 curl 更强大。
8. 总结与展望
恭喜你!你已经成功地使用 Django REST Framework (DRF) 构建了一个基本的 RESTful API。在本教程中,我们从零开始,逐步完成了以下关键步骤:
- 了解 DRF 的核心优势:认识到它在简化 API 开发方面的强大能力。
- 环境设置:安装必要的库并初始化 Django 项目和应用。
- 模型定义:创建了一个简单的 Django
Post模型来表示数据。 - 序列化器:学习了如何使用
ModelSerializer将模型数据转换为 API 可用的格式,并进行数据验证。 - API 视图:了解了如何使用
APIView和更高效的通用视图 (generics.ListCreateAPIView,generics.RetrieveUpdateDestroyAPIView) 来处理 HTTP 请求。 - URL 路由:配置了 URL 映射,将 API 请求导向正确的视图。
- API 测试:学会了如何利用 DRF 提供的可浏览的 API 界面,以及
curl等工具进行基本的 API 测试。
通过这些步骤,你已经掌握了使用 DRF 构建 Web API 的核心概念和基本流程。
下一步:进阶学习
本教程只是一个起点。Django REST Framework 还有许多强大的功能等待你去探索,包括:
- 认证 (Authentication):如何确保只有授权用户才能访问你的 API (例如 Token 认证、Session 认证)。
- 权限 (Permissions):如何细粒度地控制用户对特定资源或操作的访问。
- 分页 (Pagination):如何处理大量数据,分批返回 API 响应。
- 过滤 (Filtering)、搜索 (Searching) 和排序 (Ordering):如何允许客户端对数据进行更灵活的查询。
- 测试驱动开发 (TDD):为你的 API 编写自动化测试。
- 自定义字段和序列化器:处理更复杂的数据结构和业务逻辑。
- API 文档:使用
drf-yasg或drf-spectacular等库自动生成 Swagger/OpenAPI 文档。 - 部署 (Deployment):将你的 Django DRF 应用部署到生产环境。
继续学习和实践这些高级主题,你将能够构建出更健壮、安全和功能丰富的 RESTful API。祝你在 Django REST Framework 的旅程中一切顺利!