初探 Django REST Framework:核心概念与实践
在现代 Web 开发中,构建强大的、可互操作的 API 是核心需求之一。无论是为单页应用 (SPA)、移动客户端还是第三方服务提供数据接口,一个设计良好且易于维护的 API 都是至关重要的。Django REST Framework (DRF) 正是为了满足这一需求而生,它是一个强大而灵活的工具包,用于在 Django 项目中快速构建 Web API。
对于熟悉 Django 的开发者来说,DRF 就像是 Django 的自然延伸,它提供了一整套工具和约定,极大地简化了 API 开发过程。本文将带你初探 DRF 的世界,深入理解其核心概念,并通过一个简单的实践案例来巩固学习。
为什么选择 Django REST Framework?
在深入细节之前,先了解一下为什么 DRF 如此受欢迎:
- 强大且灵活: DRF 提供了丰富的功能,涵盖了序列化、视图处理、认证、权限、限流、分页等 API 开发的方方面面,同时又保持了高度的灵活性,允许开发者根据需求进行定制。
- 与 Django 深度集成: 作为 Django 的一个应用,DRF 与 Django ORM、URL 路由、认证系统等无缝集成,利用了 Django 自身强大的能力。
- 提高了开发效率: 提供了通用的视图类和序列化器,通过简单的配置即可实现常见的 CRUD (创建、读取、更新、删除) 操作,大大减少了样板代码。
- 优秀的文档和社区: DRF 拥有详细且易懂的官方文档,以及活跃的社区,遇到问题时很容易找到帮助。
- 提供可浏览的 API: DRF 默认提供了美观且易用的可浏览 API (Browsable API),方便开发者和使用者进行测试和调试。
总而言之,如果你正在使用 Django 并需要构建 Web API,DRF 无疑是你的首选。
入门:安装与配置
开始使用 DRF 非常简单,首先需要将其安装到你的 Python 环境中:
bash
pip install djangorestframework
然后,在你的 Django 项目的 settings.py
文件中,将 rest_framework
添加到 INSTALLED_APPS
列表中:
“`python
settings.py
INSTALLED_APPS = [
# … other apps
‘rest_framework’,
# … your apps
]
“`
完成这两步,DRF 就已经在你的 Django 项目中准备就绪了。
核心概念详解
DRF 的强大得益于其精心设计的几个核心组件。理解这些组件及其之间的协作方式,是掌握 DRF 的关键。
1. Serializers (序列化器)
概念: 序列化是 DRF 中最基础也是最重要的概念之一。简单来说,序列化器负责将复杂的数据类型(如 Django 模型实例、查询集)转换为 Python 原生数据类型(如字典、列表),以便可以轻松地将其渲染为 JSON、XML 或其他内容类型。反之,它也负责将解析后的数据(如从请求体中接收的 JSON 数据)转换回复杂类型(如模型实例),这个过程称为反序列化,通常用于数据验证和保存。
为什么需要它? Django 模型实例或查询集包含了复杂的对象结构和方法,无法直接通过 HTTP 响应发送。API 通常需要以结构化的格式(如 JSON)返回数据。序列化器就像一个翻译器,将你的数据库对象“翻译”成 API 消费者能够理解的格式。在接收数据时,它也验证输入数据的格式和内容是否符合预期。
两种主要的序列化器:
Serializer
: 一个基础的序列化器类,你可以手动定义每个字段,提供最大的灵活性。ModelSerializer
: 这是更常用的序列化器,它能自动检查指定的模型,并根据模型的字段自动生成相应的序列化器字段。它还提供了默认的.create()
和.update()
方法,使得处理模型实例的创建和更新变得非常便捷。
示例 (使用 ModelSerializer
):
假设我们有一个简单的 Django 模型 Article
:
“`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 .models import Article
from django.contrib.auth import get_user_model
User = get_user_model()
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 = ['author', 'created_at'] # 标记只读字段
“`
序列化和反序列化的用法:
“`python
序列化一个对象
article = Article.objects.first() # 获取一个文章对象
serializer = ArticleSerializer(article)
print(serializer.data) # 输出一个字典,例如: {‘id’: 1, ‘title’: ‘…’, ‘content’: ‘…’, …}
序列化一个查询集
queryset = Article.objects.all()
serializer = ArticleSerializer(queryset, many=True) # many=True 表示处理一个列表
print(serializer.data) # 输出一个字典列表
反序列化 (用于处理POST/PUT/PATCH请求的数据)
data = {‘title’: ‘New Article’, ‘content’: ‘…’, ‘author’: 1} # 假设author=1是存在的用户ID
serializer = ArticleSerializer(data=data)
if serializer.is_valid(): # 验证数据
article_instance = serializer.save() # 创建并保存新的Article对象
print(article_instance)
else:
print(serializer.errors) # 包含验证错误的字典
反序列化 (更新现有对象)
article_to_update = Article.objects.get(id=1)
update_data = {‘title’: ‘Updated Title’}
serializer = ArticleSerializer(article_to_update, data=update_data, partial=True) # partial=True 允许部分更新
if serializer.is_valid():
updated_article = serializer.save()
print(updated_article)
else:
print(serializer.errors)
“`
serializer.is_valid()
方法在验证失败时会填充 serializer.errors
属性,包含详细的错误信息。serializer.save()
方法在验证成功后,会调用序列化器内部的 create()
或 update()
方法来创建或更新模型实例。
2. Views (视图)
概念: 视图是处理传入请求并返回响应的地方。在 DRF 中,视图层构建在 Django 的视图之上,但提供了更适合 API 开发的功能,例如请求解析、响应渲染、权限和认证检查等。
核心视图类型:
-
APIView
: 这是 DRF 最基础的视图类。它继承自 Django 的View
类,但添加了对 DRF 的请求 (Request
) 和响应 (Response
) 对象的支持,以及认证、权限、限流等功能。你可以像 Django 的基于类的视图一样,定义get()
,post()
,put()
,delete()
等方法来处理不同的 HTTP 请求。“`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 ArticleSerializerclass ArticleList(APIView):
def get(self, request, format=None):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data) # DRF的Response对象def post(self, request, format=None): serializer = ArticleSerializer(data=request.data) # request.data 是解析后的数据 if serializer.is_valid(): serializer.save(author=request.user) # 假设需要当前用户作为作者 return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
“`
-
Generic API Views (通用视图): DRF 提供了一组通用的基于类的视图,它们构建在
GenericAPIView
之上,并混合了不同的Mixin
类,以实现常见的 API 行为,如列表、创建、检索、更新、删除。使用通用视图可以极大地减少代码量,因为它们已经实现了大部分逻辑。常见的通用视图及其对应的 Mixin:
*ListAPIView
(Mixin:ListModelMixin
) – 列表
*CreateAPIView
(Mixin:CreateModelMixin
) – 创建
*RetrieveAPIView
(Mixin:RetrieveModelMixin
) – 检索 (获取单个对象)
*UpdateAPIView
(Mixin:UpdateModelMixin
) – 更新
*DestroyAPIView
(Mixin:DestroyModelMixin
) – 删除
*ListCreateAPIView
(Mixins:ListModelMixin
,CreateModelMixin
) – 列表和创建
*RetrieveUpdateDestroyAPIView
(Mixins:RetrieveModelMixin
,UpdateModelMixin
,DestroyModelMixin
) – 检索、更新和删除 (常用于详情视图)使用通用视图通常需要指定
queryset
和serializer_class
:“`python
views.py (使用通用视图)
from rest_framework import generics
from .models import Article
from .serializers import ArticleSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly # 后面会讲到权限class ArticleListCreate(generics.ListCreateAPIView):
queryset = Article.objects.all() # 指定查询集
serializer_class = ArticleSerializer # 指定序列化器
permission_classes = [IsAuthenticatedOrReadOnly] # 指定权限类def perform_create(self, serializer): # 创建时关联当前用户 serializer.save(author=self.request.user)
class ArticleDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
lookup_field = ‘pk’ # 默认就是pk,可以不写,但明确写出有助于理解
“`
通用视图自动处理了请求解析、验证、序列化、数据库操作等流程,代码非常简洁。 -
ViewSets (视图集): ViewSets 是 DRF 中更高层次的抽象,它将处理一个模型或一组相关操作的逻辑集合到一个类中,而不是像传统视图那样,将列表和详情操作分别放在不同的视图类中。一个 ViewSet 可以对应多个 URL 路径和 HTTP 方法。
常见的 ViewSets:
*ViewSet
: 提供了.list()
,.create()
,.retrieve()
,.update()
,.partial_update()
,.destroy()
等方法骨架,你需要自己实现这些方法。
*ModelViewSet
: 继承自ViewSet
和通用视图的 Mixin,它提供了完整的针对模型的 CRUD 操作实现,是最常用的 ViewSet。同样需要指定queryset
和serializer_class
。“`python
views.py (使用 ModelViewSet)
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnlyclass ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
permission_classes = [IsAuthenticatedOrReadOnly] # 应用权限def perform_create(self, serializer): serializer.save(author=self.request.user)
“`
ViewSets 通常与 Routers (路由) 配合使用,由 Router 自动生成 URL 模式。
3. URLs & Routers (URL 与路由)
概念: 就像 Django 一样,你需要将视图映射到 URL。对于基于 APIView
或通用视图的少量 API 接口,你可以像处理常规 Django 视图一样手动在 urls.py
中配置 URL 模式。但对于 ViewSets,特别是 ModelViewSet
这种包含多种操作的视图集,手动配置会非常繁琐。DRF 提供了 Routers 来自动生成 URL 配置。
手动配置 (适用于 APIView
或通用视图):
“`python
urls.py (在你的app目录下)
from django.urls import path
from .views import ArticleListCreate, ArticleDetail
urlpatterns = [
path(‘articles/’, ArticleListCreate.as_view(), name=’article-list-create’),
path(‘articles/
]
“`
使用 Routers (适用于 ViewSets):
DRF 提供了 DefaultRouter
和 SimpleRouter
。DefaultRouter
提供了更多功能,包括自动生成根路由和格式后缀模式。
“`python
urls.py (在你的app目录下)
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet
router = DefaultRouter()
router.register(r’articles’, ArticleViewSet, basename=’article’) # 注册一个Viewset
urlpatterns = router.urls # 将路由生成的URL模式包含进来
“`
使用 router.register()
后,DefaultRouter
会为 ArticleViewSet
自动生成以下 URL 模式:
/articles/
(GET 用于 list, POST 用于 create)/articles/{pk}/
(GET 用于 retrieve, PUT 用于 update, PATCH 用于 partial_update, DELETE 用于 destroy)
这极大地简化了 ViewSet 的 URL 配置。
4. Requests & Responses (请求与响应)
概念: DRF 封装了 Django 的 HttpRequest
和 HttpResponse
对象,提供了更适合 API 开发的 Request
和 Response
对象。
Request
: DRF 的Request
对象扩展了 Django 的HttpRequest
,最重要的特性是request.data
属性。它包含了请求体中经过解析器解析后的数据,无论请求体是 JSON、XML 还是表单数据,你都可以通过request.data
统一访问。这比 Django 原生的request.POST
或request.body
方便得多。-
Response
: DRF 的Response
对象是一个TemplateResponse
的子类,它接收原生 Python 数据,并使用渲染器 (Renderer
) 将其渲染成客户端请求的内容类型(默认为 JSON,但在可浏览 API 中可能是 HTML)。你只需将要返回的数据传递给Response
构造函数,DRF 会自动处理内容协商和格式转换。你还可以方便地设置 HTTP 状态码。“`python
from rest_framework.response import Response
from rest_framework import status返回成功响应
return Response({‘message’: ‘Success!’}, status=status.HTTP_200_OK)
返回错误响应
return Response({‘error’: ‘Something went wrong.’}, status=status.HTTP_400_BAD_REQUEST)
“`
5. Renderers & Parsers (渲染器与解析器)
概念:
* Parsers (解析器): 负责解析客户端发送的请求体数据。DRF 根据请求头中的 Content-Type
来确定使用哪个解析器。例如,JSONParser
用于解析 JSON 数据,FormParser
和 MultiPartParser
用于解析表单数据。
* Renderers (渲染器): 负责将视图返回的 Python 数据结构渲染成特定格式的响应体。DRF 根据请求头中的 Accept
来确定使用哪个渲染器进行内容协商。例如,JSONRenderer
用于生成 JSON 响应,BrowsableAPIRenderer
用于生成可浏览 API 的 HTML 页面。
DRF 默认配置了常用的解析器和渲染器。你可以在 settings.py
中通过 REST_FRAMEWORK
设置进行全局配置,或在视图类中通过 parser_classes
和 renderer_classes
属性进行局部配置。
“`python
settings.py
REST_FRAMEWORK = {
‘DEFAULT_PARSER_CLASSES’: [
‘rest_framework.parsers.JSONParser’,
‘rest_framework.parsers.FormParser’,
‘rest_framework.parsers.MultiPartParser’,
],
‘DEFAULT_RENDERER_CLASSES’: [
‘rest_framework.renderers.JSONRenderer’,
‘rest_framework.renderers.BrowsableAPIRenderer’, # 方便测试
],
# … 其他配置
}
“`
BrowsableAPIRenderer
是 DRF 的一大特色,它使得在浏览器中访问 API 端点时能看到一个漂亮的 HTML 页面,方便进行 GET 请求并能通过表单提交 POST/PUT/PATCH 请求进行测试。
6. Authentication & Permissions (认证与权限)
概念: 安全是 API 的重要组成部分。
* Authentication (认证): 解决“你是谁?”的问题。它识别传入请求的用户身份。DRF 提供了多种认证方案,如 SessionAuthentication
(用于基于浏览器会话的认证,常用于可浏览 API 或与 Django admin 集成), TokenAuthentication
(基于 token 的认证,常用于移动应用和第三方服务), BasicAuthentication
(基本的 HTTP 认证) 等。
* Permissions (权限): 解决“你被允许做什么?”的问题。在识别用户身份后,权限检查决定该用户是否有权执行请求的操作(例如,是否允许创建、更新或删除某个资源)。DRF 提供了多种权限类,如 AllowAny
(允许所有用户), IsAuthenticated
(只允许已认证用户), IsAdminUser
(只允许管理员), IsAuthenticatedOrReadOnly
(已认证用户有完全权限,未认证用户只有读权限) 等。你也可以编写自定义权限类。
你可以通过 authentication_classes
和 permission_classes
属性在视图或 ViewSet 中应用这些安全策略,也可以在 settings.py
中进行全局配置。
“`python
views.py (在视图中应用)
from rest_framework.permissions import IsAuthenticated, IsAdminUser
class SecureView(APIView):
authentication_classes = [SessionAuthentication, TokenAuthentication] # 可以同时使用多种认证方式
permission_classes = [IsAuthenticated, IsAdminUser] # 用户必须已认证且是管理员
def get(self, request):
content = {'message': '只有认证的管理员才能看到这里。'}
return Response(content)
“`
“`python
settings.py (全局配置)
REST_FRAMEWORK = {
# … 其他配置
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.SessionAuthentication’,
‘rest_framework.authentication.TokenAuthentication’,
],
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’, # 默认要求认证
]
}
“`
注意: 权限检查是在认证之后进行的。
7. Pagination (分页)
概念: 当返回大量数据时(如列表视图),一次性返回所有数据会占用大量资源,影响性能。分页允许你限制返回结果的数量,并提供链接以获取下一页或上一页数据。
DRF 提供了多种分页器:
* PageNumberPagination
: 基于页码的分页,通过 URL 参数 ?page=...
和 ?page_size=...
控制。
* LimitOffsetPagination
: 基于偏移量和数量的分页,通过 URL 参数 ?limit=...
和 ?offset=...
控制。
* CursorPagination
: 基于游标的分页,更适合大型数据集和无限滚动的场景,因为它基于数据中的某个值而不是固定的偏移量。
你可以在 settings.py
中设置默认分页类,或在视图/ViewSet 中通过 pagination_class
属性进行局部设置。
“`python
settings.py
REST_FRAMEWORK = {
# … 其他配置
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10 # 默认每页显示10条
}
“`
“`python
views.py (在视图中局部设置)
from rest_framework.pagination import LimitOffsetPagination
class ArticleListView(generics.ListAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
pagination_class = LimitOffsetPagination # 只对这个视图应用LimitOffsetPagination
# 可以通过default_limit和max_limit等属性配置分页器
# pagination_class.default_limit = 20
“`
8. Throttling (限流)
概念: 限流用于限制用户或设备在一定时间内可以向 API 发出的请求次数,以防止滥用和服务过载。
DRF 提供了几种限流策略:
* AnonRateThrottle
: 限制匿名用户的请求速率。
* UserRateThrottle
: 限制已认证用户的请求速率。
* ScopedRateThrottle
: 根据请求的“作用域”来限制速率,例如可以为不同的 API 端点设置不同的限流策略。
限流设置通常在 settings.py
中进行全局配置,也可以在视图/ViewSet 中通过 throttle_classes
属性进行局部设置。配置时需要指定速率,例如 '100/day'
, '10/minute'
, '5/second'
。
“`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次请求
}
}
“`
“`python
views.py (在视图中局部设置)
from rest_framework.throttling import ScopedRateThrottle
class HighTrafficView(APIView):
throttle_classes = [ScopedRateThrottle]
throttle_scope = ‘high_traffic’ # 定义一个作用域
def get(self, request):
content = {'message': '这是一个高流量接口。'}
return Response(content)
settings.py 中对应配置
REST_FRAMEWORK = {
# …
‘DEFAULT_THROTTLE_RATES’: {
# …
‘high_traffic’: ’60/minute’ # 高流量接口每分钟最多60次请求
}
}
“`
实践案例:构建简单的博客 API
现在,让我们将上述核心概念串联起来,构建一个简单的博客 API,实现文章的列表、创建、检索、更新和删除功能。
1. 项目和应用设置:
假设你已经有一个 Django 项目 myproject
和一个应用 blogapi
。
bash
django-admin startproject myproject
cd myproject
python manage.py startapp blogapi
在 settings.py
中注册应用和 DRF:
“`python
myproject/settings.py
INSTALLED_APPS = [
# …
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘rest_framework’, # Add DRF
‘rest_framework.authtoken’, # 用于Token认证 (可选,但常用)
‘blogapi’, # Add your app
]
可选:配置全局认证和权限
REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.SessionAuthentication’,
‘rest_framework.authentication.TokenAuthentication’,
],
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticatedOrReadOnly’ # 默认只允许认证用户修改,匿名用户只读
],
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10, # 每页10条
}
运行迁移以创建认证和 Token 认证相关的表:
bash
python manage.py migrate
“`
2. 定义 Model:
在 blogapi/models.py
中定义文章模型:
“`python
blogapi/models.py
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at'] # 按创建时间倒序排序
def __str__(self):
return self.title
运行迁移以创建 Article 表:
bash
python manage.py makemigrations blogapi
python manage.py migrate
“`
3. 定义 Serializer:
在 blogapi/serializers.py
中定义序列化器:
“`python
blogapi/serializers.py
from rest_framework import serializers
from .models import Article
from django.contrib.auth import get_user_model
User = get_user_model()
class ArticleSerializer(serializers.ModelSerializer):
# ReadOnlyField通常用于显示相关联对象的某个属性
# source=’author.username’ 表示获取author对象的username属性
author = serializers.ReadOnlyField(source=’author.username’)
class Meta:
model = Article
fields = ['id', 'title', 'content', 'author', 'created_at', 'updated_at']
# read_only_fields = ['author', 'created_at', 'updated_at'] # 这些字段由服务器生成,客户端只读
“`
4. 定义 ViewSet:
在 blogapi/views.py
中定义 ModelViewSet
:
“`python
blogapi/views.py
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all() # 定义查询集
serializer_class = ArticleSerializer # 定义序列化器
# permissions_classes 和 authentication_classes 会继承settings.py中的默认配置,
# 除非在此处明确覆盖。这里我们沿用settings中的IsAuthenticatedOrReadOnly和Session/Token认证。
# permission_classes = [IsAuthenticatedOrReadOnly]
# authentication_classes = [SessionAuthentication, TokenAuthentication]
# 在创建文章时,自动将当前请求的用户设置为文章的作者
def perform_create(self, serializer):
serializer.save(author=self.request.user)
# 可选:如果你想让用户只能修改自己的文章,可以覆盖 get_queryset 或使用自定义权限
# def get_queryset(self):
# # 示例:只返回当前用户的文章(如果你想构建用户自己的文章列表API)
# # return self.request.user.article_set.all()
# return Article.objects.all() # 默认行为:返回所有文章
“`
5. 配置 URLs:
在 blogapi/urls.py
中使用 Router 配置 URL:
“`python
blogapi/urls.py
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet
router = DefaultRouter()
router.register(r’articles’, ArticleViewSet) # 注册 ArticleViewSet
router.urls 会自动生成URL模式
urlpatterns = router.urls
“`
在项目主 urls.py
中包含应用的 URL:
“`python
myproject/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken import views # 用于Token认证
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘blogapi.urls’)), # 包含 blogapi 的 URL
path(‘api-auth/’, include(‘rest_framework.urls’)), # 可选:用于可浏览API的登录/退出功能
path(‘api-token-auth/’, views.obtain_auth_token), # 可选:用于获取认证Token
]
“`
6. 测试 API:
- 创建用户: 运行
python manage.py createsuperuser
创建一个管理员用户。 - 启动服务器: 运行
python manage.py runserver
。 - 访问可浏览 API: 打开浏览器,访问
http://127.0.0.1:8000/api/articles/
。你应该能看到 DRF 的可浏览 API 界面。- 你可以尝试 GET 请求来查看文章列表(当前为空)。
- 要创建文章 (POST 请求),需要先登录。在可浏览 API 页面的右上角有 Login 链接,使用你创建的超级用户登录。
- 登录后,页面底部会出现一个表单,你可以填写 title 和 content 来创建文章。注意
author
字段是只读的,由服务器自动填充。
- 获取 Token (如果启用了 Token 认证): 访问
http://127.0.0.1:8000/api-token-auth/
并发送 POST 请求,请求体包含username
和password
。成功后会返回一个 Token。 - 使用 Token 访问 API: 在使用
curl
或 Postman 等工具访问 API 时,在请求头中添加Authorization: Token your_token_here
来进行认证。
例如,使用 curl
获取文章列表 (匿名访问,如果权限设置为 IsAuthenticatedOrReadOnly
则允许):
bash
curl http://127.0.0.1:8000/api/articles/
使用 curl
创建文章 (需要 Token 认证):
bash
TOKEN="your_token_here" # 替换为实际获取到的Token
curl -X POST http://127.0.0.1:8000/api/articles/ \
-H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "My First Article", "content": "This is the content of my first article."}'
这个简单的例子展示了如何利用 DRF 的 ModelViewSet
和 DefaultRouter
快速构建一个功能齐全的 RESTful API。认证、权限、分页等配置虽然在 ViewSet 中只需要一行代码或继承自全局配置,但背后是 DRF 强大的机制在支撑。
进一步探索
本文只是对 DRF 的初探,它还有许多其他强大的功能等待你去探索:
- Filtering and Searching: DRF 提供了过滤器和搜索后端,可以轻松实现基于字段的过滤和全文搜索功能。
- Testing API: DRF 提供了专门的工具和建议来测试你的 API。
- Documentation: 可以结合第三方库(如
drf-spectacular
或drf-yasg
)为你的 API 自动生成 OpenAPI (Swagger) 文档。 - Customization: 学习如何编写自定义的序列化器字段、权限类、限流类、解析器、渲染器等,以满足更复杂的业务需求。
- Signals: DRF 提供了信号机制,可以在序列化器或视图的特定阶段触发自定义逻辑。
总结
Django REST Framework 是一个为 Django 设计的优秀 Web API 开发框架。通过学习其核心概念,包括序列化器 (Serializers)、视图 (Views, Generic Views, ViewSets)、URL 路由 (URLs, Routers)、请求与响应 (Requests, Responses)、渲染器与解析器 (Renderers, Parsers)、认证 (Authentication)、权限 (Permissions)、分页 (Pagination) 和限流 (Throttling),你可以极大地提高 API 开发效率,并构建出结构清晰、功能强大的 API 服务。
希望本文能为你打开 DRF 的大门,鼓励你动手实践,深入学习更多高级特性,构建属于你的 Web API!祝你在使用 DRF 的旅程中一切顺利!