Django REST Framework 教程:构建强大 API 的完整指南 – wiki基地

Django REST Framework 教程:构建强大 API 的完整指南

Django REST Framework (DRF) 是一个强大而灵活的工具包,用于在 Django 中构建 Web API。它提供了序列化器、视图集、身份验证、权限控制、版本控制等多种功能,使得开发者可以高效地构建 RESTful API,满足各种复杂需求。本教程将深入探讨 Django REST Framework 的各个方面,并提供实际示例,帮助你掌握构建强大 API 的完整指南。

1. Django REST Framework 的优势

在使用 DRF 之前,让我们先了解一下它的优势,这将有助于你更好地理解为什么它如此受欢迎:

  • 序列化器 (Serializers): 序列化器可以将 Django 模型实例转换为 JSON、XML 等格式,用于 API 响应。同时,它们也能将 JSON 或 XML 数据转换回模型实例,用于处理 API 请求。 序列化器提供了数据验证功能,确保数据的完整性和一致性。
  • 视图集 (ViewSets): 视图集可以将相关的视图逻辑组织在一起,减少代码重复,提高代码的可读性和可维护性。 DRF 提供了多种预定义的视图集,如 ModelViewSetReadOnlyModelViewSet,可以快速构建 CRUD (创建、读取、更新、删除) API。
  • 身份验证 (Authentication): DRF 支持多种身份验证机制,包括基本身份验证、令牌身份验证、OAuth 2.0 等,可以轻松地保护 API 的安全性。
  • 权限控制 (Permissions): DRF 提供了灵活的权限控制机制,可以根据用户角色、请求方法等条件控制 API 的访问权限。
  • 版本控制 (Versioning): DRF 支持多种 API 版本控制策略,如 URL 路径版本控制、Accept Header 版本控制等,可以方便地维护不同版本的 API。
  • 可浏览 API (Browsable API): DRF 自动生成可浏览的 API 界面,方便开发者调试和测试 API。
  • 强大的定制性: DRF 提供了大量的可配置选项,可以满足各种定制化需求。

2. 准备工作:安装和配置

在开始使用 DRF 之前,需要先安装它并配置 Django 项目。

  • 安装:
    bash
    pip install djangorestframework

  • 配置:

  • 在 Django 项目的 settings.py 文件中,将 rest_framework 添加到 INSTALLED_APPS 列表中:

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

  1. (可选) 配置全局 DRF 设置。可以在 settings.py 中添加 REST_FRAMEWORK 字典,用于配置 DRF 的全局设置,例如默认的身份验证类、权限类等。

python
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # 默认需要身份验证
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', # 使用 Token 身份验证
'rest_framework.authentication.SessionAuthentication', # 使用 Session 身份验证 (用于可浏览 API)
]
}

3. 创建你的第一个 API:博客文章 API

我们将创建一个简单的博客文章 API 作为示例,演示 DRF 的基本用法。

  • 创建 Django 应用:

bash
python manage.py startapp blog

  • 定义模型 (models.py):

“`python
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

“`

  • 注册模型 (admin.py):

“`python
from django.contrib import admin
from .models import Post

admin.site.register(Post)
“`

  • 迁移数据库:

bash
python manage.py makemigrations blog
python manage.py migrate

  • 创建序列化器 (serializers.py):

blog 应用目录下创建一个 serializers.py 文件,定义 Post 模型的序列化器。

“`python
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ‘all‘ # 或者指定字段 [‘id’, ‘title’, ‘content’, ‘created_at’, ‘updated_at’]
# read_only_fields = [‘created_at’, ‘updated_at’] # 某些字段只读
“`

ModelSerializer 是一个方便的序列化器类,它可以自动从 Django 模型生成字段。 fields = '__all__' 表示序列化所有字段。 read_only_fields 定义了只读字段,这些字段只能在响应中返回,不能通过请求修改。

  • 创建视图集 (views.py):

“`python
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly

class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticatedOrReadOnly] # 只有登录用户才能修改,所有人可读
“`

ModelViewSet 提供了一组完整的 CRUD 操作 API,包括创建、读取、更新、删除和列表。 queryset 指定了要序列化的模型对象集合。 serializer_class 指定了使用的序列化器。 permission_classes 指定了访问权限。 IsAuthenticatedOrReadOnly 允许任何人读取数据,但只有经过身份验证的用户才能创建、更新或删除数据。

  • 配置 URL (urls.py):

blog 应用目录下创建一个 urls.py 文件,配置 API 的 URL。

“`python
from django.urls import path, include
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r’posts’, views.PostViewSet)

urlpatterns = [
path(”, include(router.urls)),
]
“`

DefaultRouter 会自动生成标准 RESTful API 的 URL,例如 /posts/ (列表和创建) 和 /posts/{pk}/ (读取、更新和删除)。

然后在项目级的 urls.py 中包含 blog 应用的 URL。

“`python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(‘blog.urls’)), # 将 API URL 放在 /api/ 路径下
path(‘api-auth/’, include(‘rest_framework.urls’)) # 用于可浏览API的登录/登出
]
“`

  • 启动开发服务器:

bash
python manage.py runserver

现在,你可以在浏览器中访问 http://127.0.0.1:8000/api/posts/ 查看博客文章 API。 你会看到一个可浏览的 API 界面,你可以通过它来创建、读取、更新和删除博客文章。 如果设置了 DEFAULT_PERMISSION_CLASSES,你可能需要登录才能进行修改操作。

4. 序列化器的进阶用法

  • 自定义字段 (Custom Fields):

有时,你需要自定义序列化器中的字段,例如将多个字段组合成一个字段,或者对字段的值进行转换。

“`python
class PostSerializer(serializers.ModelSerializer):
author_name = serializers.SerializerMethodField() # 添加一个自定义的只读字段

  class Meta:
      model = Post
      fields = ['id', 'title', 'content', 'created_at', 'updated_at', 'author_name']

  def get_author_name(self, obj):
      #  假设 Post 模型有一个 author 字段,它是一个 User 实例
      # return obj.author.username if obj.author else "Unknown"
      return "管理员" # 临时返回

“`

SerializerMethodField 用于创建只读的自定义字段。 你需要定义一个 get_<field_name> 方法来计算字段的值。

  • 验证 (Validation):

序列化器提供了强大的验证功能,可以确保数据的有效性。

  • 字段级别的验证: 可以在序列化器字段中添加验证器,例如 validators=[validators.MaxLengthValidator(200)]

  • 序列化器级别的验证: 可以重写 validate 方法来执行更复杂的验证逻辑。

    “`python
    class PostSerializer(serializers.ModelSerializer):
    class Meta:
    model = Post
    fields = ‘all

    def validate(self, data):
        """
        检查标题和内容是否都不为空
        """
        if not (data.get('title') or data.get('content')):
            raise serializers.ValidationError("标题和内容不能都为空.")
        return data
    

    “`

    validate 方法接收所有字段的数据作为参数,如果验证失败,应该引发 serializers.ValidationError 异常。

  • 嵌套序列化器 (Nested Serializers):

如果模型之间存在关联关系,可以使用嵌套序列化器来序列化关联的模型。 假设我们有一个 Category 模型,并且 Post 模型有一个 category 外键指向 Category 模型。

“`python
# models.py
class Category(models.Model):
name = models.CharField(max_length=100)

  def __str__(self):
      return self.name

class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name=’posts’) # 添加 category 外键
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

  def __str__(self):
      return self.title

# serializers.py
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = [‘id’, ‘name’]

class PostSerializer(serializers.ModelSerializer):
category = CategorySerializer(read_only=True) # 嵌套序列化器,只读

  class Meta:
      model = Post
      fields = ['id', 'title', 'content', 'category', 'created_at', 'updated_at']

“`

CategorySerializer 用于序列化 Category 模型。 在 PostSerializer 中,我们使用 CategorySerializer 作为 category 字段的序列化器。 read_only=True 意味着不能通过 API 请求来修改 category 字段。 如果需要允许通过 API 请求来创建或更新关联的 Category 对象,需要移除 read_only=True 并处理创建和更新的逻辑。

5. 身份验证和权限控制

DRF 提供了多种身份验证和权限控制机制,可以根据需要选择合适的方案。

  • 身份验证:

  • SessionAuthentication: 使用 Django 的 Session 机制进行身份验证,主要用于 Web 浏览器访问。

  • TokenAuthentication: 使用简单的 Token 进行身份验证,适用于移动应用和客户端。
  • JSONWebTokenAuthentication: 使用 JSON Web Token (JWT) 进行身份验证,提供更安全的身份验证机制。 需要安装 djangorestframework-jwt 库。
  • OAuth2Authentication: 使用 OAuth 2.0 协议进行身份验证,适用于第三方应用集成。 需要安装 django-oauth-toolkit 库。

  • 权限控制:

  • AllowAny: 允许所有用户访问。

  • IsAuthenticated: 只允许经过身份验证的用户访问。
  • IsAdminUser: 只允许管理员用户访问。
  • IsAuthenticatedOrReadOnly: 允许任何人读取数据,但只有经过身份验证的用户才能创建、更新或删除数据。
  • 自定义权限: 可以创建自定义权限类,实现更复杂的权限控制逻辑。

“`python
# permissions.py
from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
“””
自定义权限,只允许对象的所有者编辑它.
“””

  def has_object_permission(self, request, view, obj):
      #  读取权限允许给任何请求,
      # 所以我们总是允许 GET, HEAD, 或 OPTIONS 请求.
      if request.method in permissions.SAFE_METHODS:
          return True

      # 对象的所有者才允许写权限.
      return obj.author == request.user # 假设 Post 模型有一个 author 字段

“`

“`python
# views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
from .permissions import IsOwnerOrReadOnly

class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsOwnerOrReadOnly] # 应用自定义权限
“`

6. 版本控制

DRF 提供了多种 API 版本控制策略,可以方便地维护不同版本的 API。

  • URL 路径版本控制: 在 URL 路径中包含版本号,例如 /api/v1/posts/
  • Accept Header 版本控制:Accept 请求头中指定版本号。
  • 查询参数版本控制: 在查询参数中指定版本号,例如 /api/posts/?version=1

7. 测试

编写 API 测试对于确保 API 的正确性和稳定性至关重要。 可以使用 Django 的 TestCase 类和 DRF 的 APIClient 类来编写 API 测试。

“`python

tests.py

from django.test import TestCase
from rest_framework.test import APIClient
from .models import Post
from django.contrib.auth.models import User

class PostAPITests(TestCase):
def setUp(self):
self.client = APIClient()
self.user = User.objects.create_user(username=’testuser’, password=’testpassword’)
self.client.force_authenticate(user=self.user) # 模拟用户登录
self.post = Post.objects.create(title=’Test Post’, content=’Test Content’)

def test_get_post_list(self):
    response = self.client.get('/api/posts/')
    self.assertEqual(response.status_code, 200)

def test_create_post(self):
    data = {'title': 'New Post', 'content': 'New Content'}
    response = self.client.post('/api/posts/', data, format='json')
    self.assertEqual(response.status_code, 201)

#  更多的测试用例...

“`

8. 总结

Django REST Framework 是一个功能强大的工具包,可以帮助你快速构建高质量的 RESTful API。 本教程涵盖了 DRF 的基本概念和常用功能,包括序列化器、视图集、身份验证、权限控制和版本控制。 通过学习本教程,你将能够掌握 DRF 的核心知识,并将其应用到实际项目中。 持续学习和实践是掌握 DRF 的关键,希望本教程能为你提供一个良好的起点。 祝你使用 Django REST Framework 构建出色的 API!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部