2025-04-10
编程
00

目录

1. 安装和配置
安装 DRF
2. 创建序列化器
3. 创建视图
4. 配置路由
5. 权限和认证
6. 分页
7. 测试 API
8. 过滤器(Filtering)
使用 django-filter
9. 搜索和排序
搜索
排序
10. 自定义行为
覆盖 get_queryset 方法
添加额外的动作
11. 版本控制
基于 URL 路径的版本控制
12. 文档化 API
使用 drf-yasg
13. 测试与调试
编写测试用例
总结

Django REST Framework (DRF) 是一个强大且灵活的工具包,用于构建 Web APIs。它基于 Django 框架,提供了处理复杂 API 的功能,同时保持了易用性和可扩展性。

1. 安装和配置

安装 DRF

首先,在你的 Django 项目中安装 DRF:

bash
pip install djangorestframework

然后在项目的 settings.py 文件中的 INSTALLED_APPS 列表里添加 'rest_framework'

python
INSTALLED_APPS = [ ... 'rest_framework', ]

2. 创建序列化器

序列化器负责将复杂的 Django 模型实例或查询集转换为 Python 数据类型(如字典),然后可以轻松地渲染成 JSON 或其他格式。

假设我们有一个简单的模型 Book

python
# models.py from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=100) published_date = models.DateField()

接下来,创建一个序列化器来处理这个模型:

python
# serializers.py from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__' # 或者指定字段 ['title', 'author']

3. 创建视图

视图定义了如何处理来自客户端的请求。你可以使用基于函数的视图或基于类的视图。这里以基于类的视图为例:

python
# views.py from rest_framework import viewsets from .models import Book from .serializers import BookSerializer class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer

4. 配置路由

为了让应用程序能够响应 HTTP 请求,需要配置 URL 路由。对于视图集,可以使用 DefaultRouter 自动为你生成路由:

python
# urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import BookViewSet router = DefaultRouter() router.register(r'books', BookViewSet) urlpatterns = [ path('', include(router.urls)), ]

5. 权限和认证

为了保护你的 API,可以设置权限和认证。例如,只允许已认证的用户访问 API:

python
# views.py from rest_framework.permissions import IsAuthenticated class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer permission_classes = [IsAuthenticated] # 设置权限

你也可以在 settings.py 中全局设置默认的认证和权限策略:

python
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ], }

6. 分页

当你处理大量数据时,分页是非常有用的。DRF 提供了开箱即用的支持:

settings.py 中配置全局分页策略:

python
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10 }

或者,在特定的视图或视图集中局部配置:

python
from rest_framework.pagination import PageNumberPagination class LargeResultsSetPagination(PageNumberPagination): page_size = 1000 page_size_query_param = 'page_size' max_page_size = 10000 class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = LargeResultsSetPagination

7. 测试 API

完成上述步骤后,你可以启动 Django 开发服务器并测试你的 API:

bash
python manage.py runserver

打开浏览器访问 http://127.0.0.1:8000/books/ 查看所有书籍列表,或者使用 Postman 等工具进行更详细的测试。

8. 过滤器(Filtering)

在处理大量数据时,提供过滤功能是非常有用的。DRF 提供了多种方法来实现过滤,包括基于查询参数的简单过滤和更复杂的搜索。

使用 django-filter

首先安装 django-filter

bash
pip install django-filter

然后,在 settings.py 中添加 'django_filters'INSTALLED_APPS

python
INSTALLED_APPS = [ ... 'django_filters', ]

接着,配置 DRF 使用 DjangoFilterBackend

python
# settings.py REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] }

最后,在视图集中指定过滤字段:

python
# views.py from rest_framework import viewsets from .models import Book from .serializers import BookSerializer class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['title', 'author'] # 可以根据需要添加更多字段

或者,你可以定义一个自定义的过滤类:

python
# filters.py import django_filters from .models import Book class BookFilter(django_filters.FilterSet): min_price = django_filters.NumberFilter(field_name="price", lookup_expr='gte') max_price = django_filters.NumberFilter(field_name="price", lookup_expr='lte') class Meta: model = Book fields = ['title', 'author', 'min_price', 'max_price'] # views.py from .filters import BookFilter class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [DjangoFilterBackend] filterset_class = BookFilter

9. 搜索和排序

除了过滤,你还可以实现搜索和排序功能。

搜索

python
# settings.py 或 views.py from rest_framework.filters import SearchFilter class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [SearchFilter] search_fields = ['title', 'author']

排序

python
from rest_framework.filters import OrderingFilter class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [OrderingFilter] ordering_fields = ['published_date', 'title'] ordering = ['published_date'] # 默认排序

10. 自定义行为

有时你需要对默认的行为进行自定义,例如覆盖某些方法或添加额外的功能。

覆盖 get_queryset 方法

python
class BookViewSet(viewsets.ModelViewSet): serializer_class = BookSerializer def get_queryset(self): user = self.request.user return Book.objects.filter(owner=user)

添加额外的动作

python
from rest_framework.decorators import action from rest_framework.response import Response class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer @action(detail=True, methods=['post']) def highlight(self, request, pk=None): book = self.get_object() return Response(book.highlighted)

11. 版本控制

DRF 支持多种版本控制策略,如 URL 路径、请求头等。

基于 URL 路径的版本控制

python
# urls.py from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'books', BookViewSet, basename='book') urlpatterns = router.urls # settings.py REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', 'DEFAULT_VERSION': 'v1', 'ALLOWED_VERSIONS': ['v1', 'v2'], }

然后,你的 API URL 可能会变成 /api/v1/books//api/v2/books/

12. 文档化 API

文档对于 API 来说非常重要。DRF 提供了几种方式来生成 API 文档。

使用 drf-yasg

首先安装 drf-yasg

bash
pip install -U drf-yasg

然后在 settings.py 中添加到 INSTALLED_APPS

python
INSTALLED_APPS = [ ... 'drf_yasg', ]

配置 URL:

python
# urls.py from django.urls import path, re_path from rest_framework import permissions from drf_yasg.views import get_schema_view from drf_yasg import openapi schema_view = get_schema_view( openapi.Info( title="Book API", default_version='v1', description="Test description", terms_of_service="https://www.google.com/policies/terms/", contact=openapi.Contact(email="contact@yourapi.local"), license=openapi.License(name="BSD License"), ), public=True, permission_classes=(permissions.AllowAny,), ) urlpatterns = [ re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), ]

现在,你可以通过访问 /swagger//redoc/ 查看 API 文档。

13. 测试与调试

编写单元测试是确保 API 正确性和稳定性的重要步骤。DRF 提供了一些工具来帮助你测试 API。

编写测试用例

python
# tests.py from django.test import TestCase from rest_framework.test import APIClient from rest_framework import status from .models import Book class BookAPITestCase(TestCase): def setUp(self): self.client = APIClient() self.book_data = {'title': 'Test Book', 'author': 'Author Name', 'published_date': '2023-04-10'} self.response = self.client.post('/books/', self.book_data, format="json") def test_api_can_create_book(self): self.assertEqual(self.response.status_code, status.HTTP_201_CREATED) def test_api_can_get_books(self): books = Book.objects.all() response = self.client.get('/books/') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertContains(response, books[0].title)

总结

以上内容涵盖了从基础到中级的多个方面,包括过滤、搜索、排序、自定义行为、版本控制、文档化以及测试。