从零到一:Django REST Framework全栈开发实战指南

从零到一:Django REST Framework全栈开发实战指南

引言:API开发的痛点与解决方案

你是否还在为Django项目构建API时遇到以下问题而烦恼?序列化复杂模型时的重复劳动、权限控制的繁琐实现、API文档的缺失导致协作困难?本文将带你深入探索Django REST Framework(DRF)的核心功能,通过一个完整的代码片段分享平台案例,掌握从数据建模到API部署的全流程开发技巧。

读完本文后,你将能够:

  • 构建RESTful风格的API接口
  • 实现复杂模型的序列化与反序列化
  • 应用灵活的权限控制策略
  • 设计直观的API交互界面
  • 部署可扩展的DRF应用

项目概述:代码片段分享平台

本教程将围绕一个实用的代码片段(Snippet)分享平台展开,该平台允许用户发布、查看、编辑和删除代码片段,并支持语法高亮显示。项目采用Django REST Framework构建后端API,提供完整的CRUD(创建、读取、更新、删除)功能。

项目结构概览

rest-framework-tutorial/
├── manage.py              # Django项目管理脚本
├── requirements.txt       # 项目依赖列表
├── snippets/              # 代码片段应用
│   ├── models.py          # 数据模型定义
│   ├── serializers.py     # DRF序列化器
│   ├── views.py           # API视图
│   ├── urls.py            # URL路由配置
│   └── permissions.py     # 自定义权限类
└── tutorial/              # 项目配置
    ├── settings.py        # 项目设置
    └── urls.py            # 主URL配置

环境搭建与项目初始化

开发环境准备

首先,确保你的开发环境中安装了Python和必要的依赖管理工具:

# 创建虚拟环境
python -m venv drf-env
source drf-env/bin/activate  # Linux/Mac
# 或
drf-env\Scripts\activate     # Windows

# 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/re/rest-framework-tutorial
cd rest-framework-tutorial

# 安装依赖
pip install -r requirements.txt

项目依赖解析

requirements.txt 文件包含了项目所需的核心依赖:

Django>=2.2.0,<3.0.0
djangorestframework>=3.9.0,<3.10.0
django-filter>=2.2.0,<2.3.0
markdown>=3.1.1,<3.2.0
pygments>=2.4.2,<2.5.0
gunicorn>=19.9.0,<20.0.0
dj-database-url>=0.5.0,<0.6.0
whitenoise>=4.1.0,<4.2.0

主要依赖说明:

  • Django: Web应用框架核心
  • djangorestframework: DRF核心库
  • django-filter: 提供高级过滤功能
  • markdown: 支持API文档的Markdown渲染
  • pygments: 提供代码语法高亮功能

数据模型设计

Snippet模型实现

数据模型是任何Django应用的基础。在 snippets/models.py 中,我们定义了一个功能完善的 Snippet 模型:

from django.db import models
from pygments import highlight
from pygments.formatters.html import HtmlFormatter
from pygments.lexers import get_all_lexers, get_lexer_by_name
from pygments.styles import get_all_styles

# 获取所有可用的语法高亮器和样式
LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())


class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(
        choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(
        choices=STYLE_CHOICES, default='friendly', max_length=100)
    owner = models.ForeignKey(
        'auth.User', related_name='snippets', on_delete=models.CASCADE)
    highlighted = models.TextField()

    class Meta:
        ordering = ('created', )

    def save(self, *args, **kwargs):
        """使用pygments库生成代码的HTML高亮版本"""
        lexer = get_lexer_by_name(self.language)
        linenos = self.linenos and 'table' or False
        options = self.title and {'title': self.title} or {}
        formatter = HtmlFormatter(
            style=self.style, linenos=linenos, full=True, **options)
        self.highlighted = highlight(self.code, lexer, formatter)
        super(Snippet, self).save(*args, **kwargs)

模型设计亮点

  1. 自动生成高亮代码:重写 save() 方法,使用Pygments库自动生成代码的HTML高亮版本

  2. 丰富的字段选项

    • created: 自动记录创建时间
    • title: 代码片段标题,允许为空
    • code: 存储代码内容的文本字段
    • linenos: 布尔值,控制是否显示行号
    • language: 代码语言选择(从Pygments获取支持的语言)
    • style: 代码高亮风格选择
    • owner: 外键关联到用户,记录创建者
    • highlighted: 存储生成的HTML高亮代码
  3. 元数据配置:设置默认排序为创建时间

序列化器设计

DRF序列化器实现

序列化器(Serializer)是DRF的核心组件,负责在Django模型实例和JSON等数据格式之间进行转换。在 snippets/serializers.py 中:

from django.contrib.auth.models import User
from rest_framework import serializers

from snippets.models import Snippet


class SnippetSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    highlight = serializers.HyperlinkedIdentityField(
        view_name='snippet-highlight', format='html')

    class Meta:
        model = Snippet
        fields = ('url', 'id', 'highlight', 'owner', 'title', 'code',
                  'linenos', 'language', 'style')


class UserSerializer(serializers.HyperlinkedModelSerializer):
    snippets = serializers.HyperlinkedRelatedField(
        many=True, view_name='snippet-detail', read_only=True)

    class Meta:
        model = User
        fields = ('url', 'id', 'username', 'snippets')

序列化器特性解析

  1. HyperlinkedModelSerializer:使用超链接而非主键来表示关系,更符合RESTful API设计理念

  2. 自定义字段

    • owner: 只读字段,显示创建者用户名
    • highlight: 超链接字段,指向代码高亮视图
    • snippets: 反向关联字段,显示用户创建的所有代码片段
  3. 字段控制:精确指定需要序列化/反序列化的字段,提高API安全性和性能

视图设计与实现

ViewSet架构

DRF的ViewSet提供了一种将相关视图逻辑组合在一起的方式。在 snippets/views.py 中:

from django.contrib.auth.models import User
from rest_framework import permissions, renderers, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from snippets.models import Snippet
from snippets.permissions import IsOwnerOrReadOnly
from snippets.serializers import SnippetSerializer, UserSerializer


class SnippetViewSet(viewsets.ModelViewSet):
    """
    自动提供`list`, `create`, `retrieve`, `update`和`destroy`操作。
    额外提供`highlight`操作。
    """
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
        IsOwnerOrReadOnly, )

    @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
    def highlight(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)


class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    自动提供`list`和`detail`操作。
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

ViewSet核心特性

  1. ModelViewSet:提供完整的CRUD操作

    • list: 获取资源列表
    • create: 创建新资源
    • retrieve: 获取单个资源详情
    • update: 更新资源
    • destroy: 删除资源
  2. 自定义操作:通过@action装饰器添加自定义端点,如代码高亮功能

  3. 权限控制:结合多个权限类,实现灵活的访问控制

    • IsAuthenticatedOrReadOnly: 未认证用户只能读取
    • IsOwnerOrReadOnly: 只有所有者可以修改
  4. 对象级权限:通过perform_create方法将创建者与资源关联

权限系统设计

自定义权限类

DRF允许创建自定义权限类,以满足特定的业务需求。在 snippets/permissions.py 中:

from rest_framework import permissions


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

    def has_object_permission(self, request, view, obj):
        # 读权限允许任何请求
        if request.method in permissions.SAFE_METHODS:
            return True

        # 写权限只允许所有者
        return obj.owner == request.user

权限工作流程

mermaid

安全方法包括GET、HEAD和OPTIONS,这些方法只用于读取数据,不修改资源,因此对所有用户开放。而非安全方法(POST、PUT、PATCH、DELETE)会修改资源,因此需要严格的权限检查。

URL配置与路由

DRF路由系统

DRF提供了简单而强大的路由系统,可以自动为ViewSet生成URL配置。在项目的主 urls.py 中:

from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter

from snippets.views import SnippetViewSet, UserViewSet

# 创建路由器并注册视图集
router = DefaultRouter()
router.register(r'snippets', SnippetViewSet)
router.register(r'users', UserViewSet)

# API URL现在由路由器自动生成
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls')),
]

生成的API端点

路由器自动为我们生成了以下API端点:

HTTP方法URL路径功能描述
GET/snippets/获取所有代码片段列表
POST/snippets/创建新的代码片段
GET/snippets/{id}/获取特定代码片段详情
PUT/snippets/{id}/更新特定代码片段
DELETE/snippets/{id}/删除特定代码片段
GET/snippets/{id}/highlight/获取代码片段的高亮HTML
GET/users/获取所有用户列表
GET/users/{id}/获取特定用户详情

API测试与交互

使用DRF内置界面

DRF提供了一个直观的Web界面,方便测试API。启动开发服务器后访问 http://127.0.0.1:8000/ 即可看到API根目录。

python manage.py migrate  # 应用数据库迁移
python manage.py createsuperuser  # 创建管理员用户
python manage.py runserver  # 启动开发服务器

API交互示例

创建代码片段:

curl -X POST http://127.0.0.1:8000/snippets/ \
  -H "Content-Type: application/json" \
  -d '{"title":"Hello DRF","code":"print(\"Hello, DRF!\")","language":"python","style":"friendly"}'

获取代码片段列表:

curl http://127.0.0.1:8000/snippets/

部署与扩展

生产环境配置

项目包含了适用于生产环境的配置文件,如 Procfileruntime.txt,可以轻松部署到Heroku等平台:

# Procfile
web: gunicorn tutorial.wsgi --log-file -
# runtime.txt
python-3.7.4

部署步骤

# 安装Heroku CLI
# 登录Heroku
heroku login

# 创建Heroku应用
heroku create

# 部署代码
git push heroku main

# 运行数据库迁移
heroku run python manage.py migrate

# 创建超级用户
heroku run python manage.py createsuperuser

总结与进阶

项目核心亮点

  1. RESTful架构:遵循REST原则设计API,提供一致的接口体验
  2. 代码复用:通过ViewSet和Serializer最大化代码复用
  3. 权限控制:灵活的权限系统保护资源安全
  4. 自动生成界面:内置的API浏览界面简化测试和文档
  5. 可扩展性:模块化设计便于添加新功能

进阶学习路径

  1. 高级过滤:使用django-filter实现复杂查询
  2. 分页:实现大数据集的分页加载
  3. 缓存:添加缓存提高API性能
  4. 测试:编写单元测试和集成测试
  5. 认证:实现JWT等高级认证方式
  6. 文档:使用drf-yasg等工具生成Swagger文档

结语

Django REST Framework为Django开发者提供了构建强大API的完整解决方案。通过本文介绍的代码片段分享平台案例,我们展示了DRF的核心功能和最佳实践。无论是构建简单的CRUD API还是复杂的企业级应用,DRF都能显著提高开发效率,减少重复劳动。

希望本文能帮助你更好地理解和应用Django REST Framework。如果你有任何问题或建议,欢迎在评论区留言讨论。记得点赞、收藏并关注我们,获取更多Django和DRF的实用教程!

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值