快速了解 Django REST Framework:一篇基础教程
引言
在现代 Web 开发中,构建应用程序接口(API)变得越来越普遍,尤其是在需要前后端分离、开发移动应用或与其他服务进行数据交换的场景下。RESTful API 作为一种流行的 API 设计风格,以其简洁、高效和易于理解的特性赢得了广泛应用。
Django 作为一款功能强大的 Python Web 框架,提供了构建 Web 应用所需的一切。然而,原生 Django 在构建 RESTful API 方面并没有提供开箱即用的完整解决方案,比如数据序列化、请求解析、认证、权限控制等。这就是 Django REST Framework (DRF) 出现的意义。
Django REST Framework 是一个强大且灵活的工具包,用于构建 Web API。它建立在 Django 的基础上,利用了 Django 的 ORM、URL 路由、视图等核心组件,并为其增加了大量用于构建 API 的便利功能。通过使用 DRF,您可以极大地提高开发效率,专注于业务逻辑,而将 API 的基础设施交给框架处理。
本篇文章将作为一篇基础教程,带领您快速入门 DRF。我们将从零开始搭建一个简单的 Django 项目,集成 DRF,并学习 DRF 中最核心的概念:序列化器(Serializers)、视图(Views)和 URL 配置。通过构建一个简单的 Todo List API,您将亲身体验 DRF 的魅力。
本文目标:
- 理解 DRF 的作用和优势。
- 学会如何在 Django 项目中安装和配置 DRF。
- 掌握 DRF 中序列化器(Serializers)的基本用法。
- 理解 DRF 中视图(Views)的不同类型及其用途。
- 学会如何配置 DRF API 的 URL。
- 通过一个简单的例子,贯穿 DRF 的核心组件,构建一个功能齐全的 RESTful API。
- 初步了解 DRF 的认证和权限机制。
前置知识:
- 对 Python 编程有基本了解。
- 熟悉 Django 框架的基础知识(如模型、视图、URL 配置、ORM 等)。
让我们开始吧!
1. DRF 是什么?为什么要用它?
什么是 REST?
在深入了解 DRF 之前,有必要简要回顾一下 REST(Representational State Transfer)。REST 是一种架构风格,定义了一组约束,用于创建 Web 服务。遵循 RESTful 风格的 API 通常具备以下特点:
- 无状态 (Stateless): 服务器不存储客户端的状态,每个请求都包含完成请求所需的所有信息。
- 客户端-服务器 (Client-Server): 客户端和服务器之间分离,允许独立发展。
- 统一接口 (Uniform Interface): 定义了一套标准的接口约束,如资源通过 URI 标识,通过 HTTP 方法(GET, POST, PUT, PATCH, DELETE)操作资源。
- 可缓存 (Cacheable): 响应可以被标记为可缓存,提高性能。
- 分层系统 (Layered System): 服务器和客户端之间的通信可以经过多个中间层。
- 按需代码 (Code-On-Demand, 可选): 服务器可以临时扩展或定制客户端功能(例如,通过提供脚本)。
RESTful API 通常以 JSON 或 XML 等格式表示资源。
DRF 的作用和优势
DRF 是在 Django 框架基础上构建 RESTful API 的工具包。它为 Django 添加了许多 API 特有的功能层,极大地简化了 API 的开发过程。其主要优势包括:
- 强大的序列化功能: 轻松地将 Django ORM 对象(模型实例、查询集)转换为 JSON、XML 等表示形式,反之亦然(反序列化用于处理客户端发送的数据,进行验证和保存)。
- 灵活的视图类: 提供了基于类的视图(APIView, GenericAPIView, Viewsets),极大地简化了不同 HTTP 方法(GET, POST, PUT, DELETE 等)的处理逻辑。特别是通用视图和 Viewsets,通过 Mixins 模式提供了常见的 CRUD (Create, Retrieve, Update, Delete) 操作的实现。
- 开箱即用的认证和权限系统: 支持多种认证方式(Session, Token, OAuth2 等)和权限控制(如
IsAuthenticated,IsAdminUser等),方便保护 API 接口。 - 请求解析和响应渲染: 自动处理不同内容类型的请求数据(如 JSON, 表单数据)和不同格式的响应(JSON, XML, HTML)。
- 可浏览的 API (Browsable API): DRF 提供了一个非常有用的 Web 界面,可以直接在浏览器中查看和测试 API 端点,这对于开发和调试非常有帮助。
- 自动化 URL 配置: 使用 Routers 可以方便地为 Viewsets 自动生成复杂的 URL 模式。
- 内置的限流 (Throttling) 支持: 控制客户端访问 API 的频率,防止滥用。
- 文档生成支持: 方便集成 OpenAPI (Swagger) 等文档工具。
总而言之,DRF 提供了一套完整的工具链和约定,让您能够快速、高效、规范地构建高质量的 RESTful API。
2. 项目搭建与 DRF 集成
首先,我们需要创建一个新的 Django 项目并安装 DRF。
步骤 1: 创建 Django 项目和应用
打开终端,执行以下命令:
“`bash
创建虚拟环境(推荐)
python -m venv myenv
source myenv/bin/activate # macOS/Linux
或 .\myenv\Scripts\activate # Windows
安装 Django 和 DRF
pip install django djangorestframework
创建 Django 项目
django-admin startproject myapi
cd myapi
创建 Django 应用
python manage.py startapp todo_app
运行迁移(创建默认数据库表)
python manage.py migrate
创建超级用户(方便访问 Django Admin)
python manage.py createsuperuser
“`
步骤 2: 配置 DRF
打开项目根目录下的 myapi/settings.py 文件。在 INSTALLED_APPS 列表中添加 'rest_framework' 和您刚刚创建的应用 'todo_app'。
“`python
myapi/settings.py
INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
# 添加 DRF
‘rest_framework’,
# 添加你的应用
‘todo_app’,
]
… 其他设置 …
“`
至此,您已经在 Django 项目中成功集成了 Django REST Framework。
3. 核心概念:序列化器 (Serializers)
在 DRF 中,序列化器是用于在复杂数据类型(如 Django 模型实例、查询集)和原生 Python 数据类型(如字典、列表)之间进行转换的关键组件。这些原生 Python 数据类型可以轻松地被渲染成 JSON、XML 等格式发送给客户端,或者从客户端接收这些格式的数据并转换回原生 Python 数据类型,以便进行验证和保存到数据库。
简而言之,序列化器负责:
- 序列化: 将模型对象等复杂数据转换为可传输的格式(如字典)。
- 反序列化: 将接收到的数据(如 JSON 对应的字典)转换为模型对象或验证其有效性,并可以选择保存到数据库。
DRF 提供了 Serializer 类作为基础,以及一个更常用的 ModelSerializer 类,后者可以根据 Django 模型自动生成序列化器字段。
创建一个简单的模型
为了演示序列化器,我们先创建一个简单的 Django 模型。在 todo_app/models.py 中定义一个 Todo 模型:
“`python
todo_app/models.py
from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True, null=True)
completed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
“`
别忘了运行迁移命令来创建对应的数据库表:
bash
python manage.py makemigrations
python manage.py migrate
创建序列化器
现在,创建一个序列化器来处理 Todo 模型。在 todo_app 应用目录下创建一个新文件 serializers.py:
“`python
todo_app/serializers.py
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
# 指定要序列化/反序列化的字段
# ‘all‘ 表示包含模型中的所有字段
# 或者可以使用 fields = [‘id’, ‘title’, ‘completed’] 指定特定字段
fields = ‘all‘
# 也可以使用 exclude = [‘created_at’] 来排除某些字段
“`
这里我们使用了 ModelSerializer,它是 DRF 提供的一个快捷方式,可以自动根据 Meta 类中指定的 model 来生成相应的字段。fields = '__all__' 表示序列化器将包含 Todo 模型的所有字段。
序列化器的使用(概念演示)
虽然我们还没有视图,但可以在 Python Shell 中简单演示序列化器的用法:
bash
python manage.py shell
“`python
在 Python Shell 中
from todo_app.models import Todo
from todo_app.serializers import TodoSerializer
创建一个 Todo 实例
todo_item = Todo.objects.create(title=”学习 DRF”, description=”阅读 DRF 文档”, completed=False)
序列化单个对象
serializer = TodoSerializer(todo_item)
print(serializer.data)
输出示例:{‘id’: 1, ‘title’: ‘学习 DRF’, ‘description’: ‘阅读 DRF 文档’, ‘completed’: False, ‘created_at’: ‘…’, ‘updated_at’: ‘…’}
序列化查询集(多个对象)
queryset = Todo.objects.all()
serializer = TodoSerializer(queryset, many=True) # important: many=True for querysets
print(serializer.data)
输出示例:[{‘id’: 1, ‘title’: ‘…’, …}, {‘id’: 2, ‘title’: ‘…’, …}, …]
反序列化数据 (模拟接收到的 JSON 数据)
data = {‘title’: ‘购买牛奶’, ‘completed’: True}
serializer = TodoSerializer(data=data) # 注意这里使用 data 参数
检查数据是否有效
if serializer.is_valid():
# 有效数据可以通过 .save() 创建新的模型实例
new_todo = serializer.save()
print(“新建的 Todo:”, new_todo)
else:
print(“数据无效:”, serializer.errors)
“`
这个例子展示了序列化器如何将模型对象转换为字典(通过 .data 属性),以及如何接收字典数据并通过 .is_valid() 和 .save() 进行验证和创建模型实例。
关键点:
- 使用
ModelSerializer可以大大简化基于模型的序列化器创建。 Meta类中的model和fields或exclude属性是必需的。- 序列化单个对象时直接传入对象;序列化查询集时,必须设置
many=True。 - 反序列化时,将数据作为
data参数传入。 - 调用
is_valid()进行数据验证,验证通过后才能调用save()。
4. 核心概念:视图 (Views)
在 Django 中,视图负责接收请求并返回响应。DRF 在 Django 视图的基础上提供了更适合构建 API 的视图类。它们自动处理请求和响应的序列化、反序列化、认证、权限等逻辑。
DRF 提供了几种主要的视图类型:
APIView: DRF 提供的最基础的视图类。它继承自 Django 的View,并增加了 DRF 特有的功能,如请求解析、认证、权限、限流等。您需要在APIView的方法(如get,post,put,delete)中手动处理序列化、反序列化和数据库操作。它提供了最大的灵活性。- 通用视图 (Generic Views): 一组基于
APIView构建的视图类,它们集成了用于常见 API 操作(如列表、详情、创建、更新、删除)的 Mixins。使用通用视图可以减少编写重复代码。例如,ListAPIView用于获取列表,RetrieveAPIView用于获取单个对象。 - 视图集 (Viewsets): 比通用视图更进一步,将一组相关的视图逻辑(通常是针对同一个模型的 CRUD 操作)捆绑到一个类中。一个 Viewset 可以替代多个通用视图。Viewsets 通常与 DRF 的 Router 一起使用,自动生成 URL 配置。这是构建 RESTful API 时最推荐的方式。
使用 APIView (基础示例)
为了理解 DRF 视图的基础,我们先看一个简单的 APIView 示例。我们创建一个视图来获取所有 Todo 项的列表并允许创建新的 Todo 项。
“`python
todo_app/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Todo
from .serializers import TodoSerializer
class TodoListCreateAPIView(APIView):
“””
获取所有 Todo 或创建一个新的 Todo
“””
def get(self, request, format=None):
# 获取所有 Todo 对象
todos = Todo.objects.all()
# 使用序列化器序列化查询集
serializer = TodoSerializer(todos, many=True)
# 返回 JSON 响应
return Response(serializer.data)
def post(self, request, format=None):
# 使用序列化器反序列化接收到的数据
serializer = TodoSerializer(data=request.data)
# 检查数据是否有效
if serializer.is_valid():
# 保存到数据库
serializer.save()
# 返回新创建的对象数据和 201 Created 状态码
return Response(serializer.data, status=status.HTTP_201_CREATED)
# 如果数据无效,返回错误信息和 400 Bad Request 状态码
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
“`
这个 APIView 包含了 get 和 post 方法,分别对应处理 GET 和 POST 请求。在 get 方法中,我们获取所有 Todo 对象,使用 TodoSerializer 序列化它们(注意 many=True),然后将序列化后的数据包装在 Response 对象中返回。在 post 方法中,我们获取请求数据 (request.data),使用 TodoSerializer 进行反序列化和验证,如果有效则保存并返回新创建的对象和 201 状态码,否则返回错误信息和 400 状态码。
使用 GenericAPIView 和 Mixins (通用示例)
GenericAPIView 类继承自 APIView,并提供了常用的属性(如 queryset, serializer_class)和方法。它通常与 Mixins 一起使用,以提供更简洁的代码来实现常见的 API 操作。
常见的 Mixins 包括:
ListModelMixin: 提供.list()方法,用于获取对象列表。CreateModelMixin: 提供.create()方法,用于创建新对象。RetrieveModelMixin: 提供.retrieve()方法,用于获取单个对象详情。UpdateModelMixin: 提供.update()和.partial_update()方法,用于更新对象。DestroyModelMixin: 提供.destroy()方法,用于删除对象。
我们可以使用 GenericAPIView 和 ListModelMixin, CreateModelMixin 来重写上面的列表和创建视图:
“`python
todo_app/views.py (在前面的基础上添加)
from rest_framework import generics # 导入通用视图模块
… 其他导入 …
class TodoListCreateGenericView(generics.ListCreateAPIView):
“””
使用通用视图实现获取所有 Todo 或创建一个新的 Todo
ListCreateAPIView 结合了 ListModelMixin 和 CreateModelMixin
“””
queryset = Todo.objects.all()
serializer_class = TodoSerializer
对于详情、更新、删除
class TodoDetailUpdateDestroyGenericView(generics.RetrieveUpdateDestroyAPIView):
“””
使用通用视图实现获取、更新、删除单个 Todo
RetrieveUpdateDestroyAPIView 结合了 RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
“””
queryset = Todo.objects.all()
serializer_class = TodoSerializer
# 注意:对于详情、更新、删除,需要根据 URL 中的主键或 slug 来查找对象
# GenericAPIView 会自动处理 object lookup (通常使用 pk_url_kwarg 或 slug_url_kwarg)
“`
可以看到,使用通用视图后代码大大减少了。我们只需要指定 queryset 和 serializer_class,然后继承相应的通用视图类即可。ListCreateAPIView 继承自 GenericAPIView 并混入了 ListModelMixin 和 CreateModelMixin,所以它同时支持 GET (列表) 和 POST (创建) 请求。RetrieveUpdateDestroyAPIView 同理,支持 GET (详情), PUT/PATCH (更新), DELETE (删除) 请求。
使用 Viewsets (推荐方式)
Viewsets 将列表、详情、创建、更新、删除等操作捆绑在一个类中。它们不提供 get, post 等方法,而是提供 list, create, retrieve, update, partial_update, destroy 等方法。Viewsets 通常与 DRF 的 Router 配合使用,由 Router 自动生成 URL 模式。
最常用的 Viewset 是 ModelViewSet,它继承了 GenericViewSet 并混入了所有标准的 Mixins (ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin)。使用 ModelViewSet 可以用最少的代码实现一个模型的完整 CRUD API。
让我们使用 ModelViewSet 来实现 Todo 的全部 API 功能:
“`python
todo_app/views.py (替换或添加 Viewset)
from rest_framework import viewsets # 导入 Viewset 模块
… 其他导入 …
class TodoViewSet(viewsets.ModelViewSet):
“””
一个简单的 Viewset,用于查看和编辑 Todo 实例
ModelViewSet 提供了 list, create, retrieve, update, destroy 方法
“””
queryset = Todo.objects.all()
serializer_class = TodoSerializer
# 可以在 Viewset 中添加其他属性,如 filter_backends, pagination_class, authentication_classes, permission_classes 等
“`
这就是使用 ModelViewSet 的全部代码!它将自动提供 /todos/ (GET list, POST create) 和 /todos/{id}/ (GET retrieve, PUT update, PATCH partial_update, DELETE destroy) 等端点。
为什么推荐 Viewsets?
- 简洁: 用一个类处理所有 CRUD 操作。
- 约定优于配置: Viewsets 和 Routers 的配合是构建 RESTful API 的标准方式。
- 与 Router 无缝集成: 简化 URL 配置。
- 代码复用: Viewsets 可以继承和混入其他类,方便定制。
虽然在本教程中我们主要关注 Viewsets,但理解 APIView 和通用视图有助于您在需要更精细控制或实现非标准 API 时做出正确的选择。
5. 核心概念:URL 配置
在 Django 中,我们需要将 URL 模式映射到视图函数或视图类。DRF 为 Viewsets 提供了一种更便捷的 URL 配置方式:Router。
为 APIView 或 通用视图 配置 URL
如果使用 APIView 或 GenericAPIView,URL 配置与原生 Django 类似,只是映射的是 DRF 的视图类。
在 todo_app/urls.py 中(如果文件不存在,则创建它):
“`python
todo_app/urls.py (如果使用 APIView 或 通用视图)
from django.urls import path
from .views import TodoListCreateAPIView, TodoDetailUpdateDestroyGenericView # 对应 APIView 或 通用视图
from .views import TodoListCreateGenericView # 如果使用 GenericAPIView 的 ListCreateAPIView
urlpatterns = [
# path(‘todos/’, TodoListCreateAPIView.as_view(), name=’todo-list-create’), # 对应 APIView
# path(‘todos/
path('todos/', TodoListCreateGenericView.as_view(), name='todo-list-create'), # 对应 GenericAPIView
path('todos/<int:pk>/', TodoDetailUpdateDestroyGenericView.as_view(), name='todo-detail-update-destroy'), # 对应 GenericAPIView
]
“`
然后,在项目的根 urls.py (myapi/urls.py) 中包含应用 (todo_app) 的 URL 模式:
“`python
myapi/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
# 包含 todo_app 的 URL 模式
path(‘api/’, include(‘todo_app.urls’)),
]
“`
为 Viewset 配置 URL (使用 Router)
如果使用 Viewsets,Router 可以自动为 Viewset 生成 URL 模式。这是 DRF 推荐的方式。
在 todo_app/urls.py 中,使用 DRF 的 Router:
“`python
todo_app/urls.py (如果使用 Viewset)
from rest_framework.routers import DefaultRouter
from .views import TodoViewSet
创建 Router 实例
router = DefaultRouter()
注册 Viewset 到 Router
第一个参数是 URL 前缀 (这里是 ‘todos’)
第二个参数是 Viewset 类
第三个参数是 basename,用于生成 URL 名称(可选,但推荐)
router.register(r’todos’, TodoViewSet, basename=’todo’)
Router 会自动生成 URL 模式:
/todos/ (GET, POST) -> list, create
/todos/{pk}/ (GET, PUT, PATCH, DELETE) -> retrieve, update, partial_update, destroy
将 Router 生成的 URL 模式添加到 urlpatterns
urlpatterns = router.urls
您也可以添加其他非 Viewset 的 URL
from django.urls import path
urlpatterns += [
path(‘some-other-endpoint/’, SomeAPIView.as_view(), name=’some-name’),
]
“`
然后在项目的根 urls.py (myapi/urls.py) 中包含应用 (todo_app) 的 URL 模式,与上面使用 APIView 的方式一样:
“`python
myapi/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
# 包含 todo_app 的 URL 模式 (使用 Router 生成的)
path(‘api/’, include(‘todo_app.urls’)),
]
“`
通过这种方式,Router 自动帮我们配置了所有与 TodoViewSet 相关的 RESTful URL 端点,非常方便。
6. 构建并测试简单的 Todo API (使用 Viewset)
现在我们已经有了模型、序列化器和使用 Viewset 的视图,以及对应的 URL 配置。我们可以运行服务器并测试我们的 API 了。
确保您已经在 todo_app/models.py, todo_app/serializers.py, todo_app/views.py, todo_app/urls.py, myapi/urls.py, myapi/settings.py 中按照上面的示例填写了代码,并且运行了 makemigrations 和 migrate。
步骤 1: 启动开发服务器
在项目根目录下运行:
bash
python manage.py runserver
步骤 2: 使用浏览器访问可浏览 API
打开浏览器,访问 http://127.0.0.1:8000/api/todos/。
如果一切正常,您应该会看到 DRF 提供的可浏览 API 界面。这个界面非常有用,它显示了当前端点的可用 HTTP 方法(GET, POST),您可以直接在浏览器中查看数据、提交 POST 请求(创建新 Todo)。
- 查看列表 (GET): 直接访问
http://12.0.0.1:8000/api/todos/即可看到所有 Todo 项的列表(一开始可能是空的)。 - 创建 Todo (POST): 在
/api/todos/页面的底部,您会看到一个表单。填写title和description(可选),completed默认是false,然后点击 POST 按钮即可创建一个新的 Todo。创建成功后,页面会跳转到新创建的 Todo 的详情页,并显示 201 Created 状态码。 - 查看详情 (GET): 在列表页点击某个 Todo 的 URL (例如
http://127.0.0.1:8000/api/todos/1/),或者直接在浏览器中访问/api/todos/{id}/(例如/api/todos/1/),即可看到单个 Todo 的详情。 - 更新 Todo (PUT/PATCH): 在详情页,页面的底部会显示 PUT 和 PATCH 表单。您可以修改字段值,然后提交以更新该 Todo。PUT 需要提交所有字段,PATCH 只提交需要修改的字段。
- 删除 Todo (DELETE): 在详情页,页面的底部会显示 DELETE 按钮。点击即可删除该 Todo。
可浏览 API 是 DRF 提供的一个强大特性,它使得调试和初步测试 API 变得非常方便。
步骤 3: 使用工具测试 API (可选)
除了可浏览 API,您也可以使用 Postman, Insomnia, 或者命令行工具如 curl 来测试 API。
例如,使用 curl 创建一个 Todo:
bash
curl -X POST -H "Content-Type: application/json" -d '{"title": "购买水果", "completed": false}' http://127.0.0.1:8000/api/todos/
使用 curl 获取 Todos 列表:
bash
curl http://127.0.0.1:8000/api/todos/
使用 curl 获取 ID 为 1 的 Todo 详情:
bash
curl http://127.0.0.1:8000/api/todos/1/
使用 curl 更新 ID 为 1 的 Todo (PATCH):
bash
curl -X PATCH -H "Content-Type: application/json" -d '{"completed": true}' http://127.0.0.1:8000/api/todos/1/
通过这些步骤,您已经成功构建并测试了一个基本的 Todo RESTful API。
7. 认证 (Authentication) 与权限 (Permissions) (初步了解)
构建 API 时,控制谁可以访问哪些资源以及执行哪些操作是至关重要的。DRF 提供了一套灵活的认证和权限系统。
- 认证 (Authentication): 用于验证请求的发出者是谁。常见的认证方式包括 Session 认证 (用于浏览器会话)、Token 认证 (用于移动应用或第三方服务)、OAuth2 等。
- 权限 (Permissions): 在认证成功后,用于判断该用户是否具有执行某个操作的权限。常见的权限类包括
AllowAny(允许任何人)、IsAuthenticated(只允许认证用户)、IsAdminUser(只允许管理员用户)、IsAuthenticatedOrReadOnly(认证用户可写,其他用户只读) 等。
配置认证和权限
认证和权限可以在全局配置 (settings.py) 或在单个视图/Viewset 中配置。
全局配置 (settings.py):
“`python
myapi/settings.py
REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.SessionAuthentication’, # 用于浏览器会话认证
‘rest_framework.authentication.TokenAuthentication’, # 用于基于 Token 的认证 (需要安装 rest_framework.authtoken)
],
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticatedOrReadOnly’, # 默认只允许认证用户修改,其他用户只读
],
# 其他 DRF 设置
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10 # 设置默认分页大小
}
如果使用了 TokenAuthentication,需要在 INSTALLED_APPS 中添加
INSTALLED_APPS = [
…
‘rest_framework.authtoken’,
…
]
并运行 python manage.py migrate
“`
在 settings.py 中配置的认证和权限类将应用于所有 DRF 视图,除非在视图中被覆盖。
视图/Viewset 局部配置:
您可以在视图类中设置 authentication_classes 和 permission_classes 属性来覆盖全局设置:
“`python
todo_app/views.py
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated, AllowAny # 导入权限类
from rest_framework.authentication import TokenAuthentication # 导入认证类
… 其他导入 …
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
# 覆盖全局设置,只允许认证用户访问所有 Todo 操作
permission_classes = [IsAuthenticated]
# authentication_classes = [TokenAuthentication] # 如果只使用 Token 认证
# 如果不设置 authentication_classes,将使用全局配置
例如,一个公共接口允许任何人访问
class PublicView(APIView):
permission_classes = [AllowAny]
# …
“`
简单测试权限
如果您在 TodoViewSet 中设置了 permission_classes = [IsAuthenticated],那么:
- 使用可浏览 API 时,如果您没有登录 (通过 Django admin 登录),尝试 POST、PUT、PATCH、DELETE 请求会收到 403 Forbidden 响应。GET 请求可能取决于是否配置了
IsAuthenticatedOrReadOnly或IsAuthenticated。如果是IsAuthenticated,即使是 GET 也需要认证。 - 使用
curl等工具时,如果您的请求没有携带认证信息 (例如 Token 或 Session Cookie),尝试执行需要认证的操作也会收到 403 响应。
为了使用 Token 认证,您需要:
- 在
settings.py的INSTALLED_APPS中添加rest_framework.authtoken并运行python manage.py migrate。 -
为用户生成 Token。可以通过 Django Shell 或创建一个 API 端点来实现。例如,通过 Django Shell 为用户生成 Token:
bash
python manage.py shell
“`python
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token假设你有一个用户名为 ‘myuser’ 的用户
user = User.objects.get(username=’myuser’)
创建或获取该用户的 Token
token, created = Token.objects.get_or_create(user=user)
print(token.key)
3. 在客户端请求头中携带 Token,格式为 `Authorization: Token <your_token_key>`。例如,使用 `curl` 携带 Token 获取 Todo 列表:bash
curl -H “Authorization: Token YOUR_TOKEN_KEY” http://127.0.0.1:8000/api/todos/
“`
认证和权限是构建安全 API 的重要部分,DRF 提供了强大的支持。本教程只进行了初步介绍,建议在实际开发中深入学习不同认证方式和自定义权限类的用法。
8. 更多 DRF 特性 (简单提及)
DRF 还提供了许多其他有用的特性:
- 分页 (Pagination): 轻松地对列表视图的结果进行分页,避免一次返回大量数据。可以在
settings.py或视图中配置分页类和大小。 - 过滤 (Filtering) 和搜索 (Searching): 允许客户端通过 URL 参数对结果集进行过滤和搜索。通常结合
django-filter库使用。 - 版本控制 (Versioning): 支持在 URL 或请求头中指定 API 版本,方便管理 API 的演进。
- 限流 (Throttling): 控制客户端在一定时间内可以发起的请求次数,保护 API 免受恶意访问。
- 自定义渲染器和解析器: 支持除了 JSON 和 HTML 以外的多种数据格式。
- 国际化和本地化。
- 测试工具: 提供了
APIClient等方便进行 API 测试的工具。 - Schema 生成与文档: 支持生成 OpenAPI (Swagger) 规范,方便生成 API 文档。
这些特性使得 DRF 不仅适用于简单的 API,也适用于构建复杂、健壮的企业级 API。
9. 总结与后续学习
恭喜您!通过本教程,您已经对 Django REST Framework 的核心概念(序列化器、视图、URL 配置)有了初步了解,并通过构建一个简单的 Todo API 实践了这些概念。您也初步接触了 DRF 的认证和权限系统,以及其他一些重要特性。
DRF 是一个功能非常强大的框架,本教程仅仅是入门。要更深入地掌握 DRF,建议您:
- 阅读官方文档: DRF 的官方文档非常详细和全面,是最好的学习资源。
- 深入学习序列化器: 了解各种字段类型、验证选项、嵌套序列化、自定义序列化器等。
- 深入学习视图: 掌握各种通用视图和 Mixins 的用法,了解何时使用
APIView。 - 学习认证和权限: 深入了解不同认证方式的实现细节,学习如何编写自定义权限类来满足更复杂的业务需求。
- 探索其他特性: 研究分页、过滤、搜索、版本控制、限流等特性,并将它们应用到您的项目中。
- 实践: 尝试构建更复杂的 API 项目,不断练习。
Django REST Framework 极大地提高了在 Django 中构建 API 的效率和规范性。掌握它将是您作为 Django 开发者的一项宝贵技能。
希望这篇基础教程对您有所帮助!祝您在 DRF 的学习和使用中一切顺利!