1. 为什么选择Django Rest Framework构建API
作为Python开发者,我使用过各种API框架,但Django Rest Framework(DRF)始终是我的首选。它不仅继承了Django的优秀特性,还针对API开发做了大量优化。在实际项目中,DRF的表现尤为出色:
- 开发效率高:内置的序列化器、视图集和路由器可以节省大量重复代码
- 文档完善:官方文档详尽,社区支持强大
- 扩展性强:从简单API到复杂业务系统都能胜任
- 生态丰富:与Django生态无缝集成,支持各种插件和扩展
我最近用DRF为一个电商项目构建了商品管理API,仅用3天就完成了基础功能开发,这充分证明了它的高效性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目初始化
2.1 Python环境配置
我推荐使用Python 3.8+版本,这是目前生产环境最稳定的选择。安装完成后,务必设置虚拟环境:
bash复制# 创建项目目录
mkdir drf_api_project && cd drf_api_project
# 创建虚拟环境(推荐使用venv)
python -m venv venv
# 激活虚拟环境
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate
注意:虚拟环境可以隔离项目依赖,避免不同项目间的包冲突。这是专业开发的必备实践。
2.2 安装核心依赖
安装Django和DRF时,建议指定版本以确保稳定性:
bash复制pip install django==4.2.0 djangorestframework==3.14.0
验证安装是否成功:
bash复制python -m django --version
# 应输出:4.2.0
2.3 初始化Django项目
创建项目和应用时,我习惯使用这种结构:
bash复制django-admin startproject core .
python manage.py startapp api
这样设置后,项目目录结构更清晰:
code复制drf_api_project/
├── core/ # 项目配置
├── api/ # API应用
├── manage.py
└── venv/ # 虚拟环境
在core/settings.py中添加应用:
python复制INSTALLED_APPS = [
...
'rest_framework',
'api.apps.ApiConfig',
]
3. 数据模型与序列化器
3.1 设计数据模型
假设我们要构建一个博客API,首先定义文章模型:
python复制# api/models.py
from django.db import models
class Article(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)
is_published = models.BooleanField(default=False)
def __str__(self):
return self.title
执行迁移:
bash复制python manage.py makemigrations
python manage.py migrate
3.2 创建序列化器
序列化器是DRF的核心组件,我通常会创建专门的serializers.py:
python复制# api/serializers.py
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'title', 'content', 'is_published', 'created_at']
read_only_fields = ['id', 'created_at']
def validate_title(self, value):
"""自定义标题验证"""
if len(value) < 5:
raise serializers.ValidationError("标题至少需要5个字符")
return value
经验分享:总是明确指定
fields而不是用__all__,这样可以避免意外暴露敏感字段。
4. 视图与路由配置
4.1 视图集的使用
DRF的视图集(ViewSets)可以大幅减少代码量:
python复制# api/views.py
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
def get_queryset(self):
"""重写查询集,只返回已发布文章"""
queryset = super().get_queryset()
if not self.request.user.is_staff:
queryset = queryset.filter(is_published=True)
return queryset
4.2 路由配置
使用DRF的DefaultRouter可以自动生成标准路由:
python复制# core/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from api.views import ArticleViewSet
router = DefaultRouter()
router.register(r'articles', ArticleViewSet)
urlpatterns = [
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls')),
]
这样配置后,你将自动获得以下端点:
GET /api/articles/- 文章列表POST /api/articles/- 创建文章GET /api/articles/<id>/- 文章详情- 等等...
5. 权限与认证
5.1 全局权限设置
在core/settings.py中配置默认权限:
python复制REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
}
5.2 自定义权限
对于更细粒度的控制,可以创建自定义权限类:
python复制# api/permissions.py
from rest_framework import permissions
class IsAuthorOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.author == request.user
然后在视图中使用:
python复制class ArticleViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly, IsAuthorOrReadOnly]
...
6. 测试与文档
6.1 编写API测试
DRF提供了强大的测试工具:
python复制# api/tests.py
from rest_framework.test import APITestCase
from django.urls import reverse
from .models import Article
class ArticleAPITests(APITestCase):
def setUp(self):
self.article = Article.objects.create(
title="Test Article",
content="Test content",
is_published=True
)
def test_article_list(self):
url = reverse('article-list')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
6.2 自动生成文档
DRF支持多种文档格式,我最喜欢的是Swagger:
bash复制pip install drf-yasg
配置:
python复制# core/urls.py
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Blog API",
default_version='v1',
),
public=True,
)
urlpatterns = [
...
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0)),
]
访问/swagger/即可看到交互式API文档。
7. 性能优化技巧
在实际项目中,我总结了这些优化经验:
- 查询优化:
python复制class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.select_related('author').prefetch_related('tags')
- 分页控制:
python复制REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20
}
- 缓存策略:
python复制from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
@method_decorator(cache_page(60*15), name='dispatch')
class ArticleViewSet(viewsets.ModelViewSet):
...
8. 常见问题与解决方案
Q1: 如何处理复杂的关系字段?
A: 使用嵌套序列化器:
python复制class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ['id', 'content']
class ArticleSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True, read_only=True)
Q2: 如何自定义响应格式?
A: 重写视图的list或retrieve方法:
python复制def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
return Response({
'status': 'success',
'data': response.data
})
Q3: 文件上传如何处理?
A: 使用FileField或ImageField:
python复制class DocumentSerializer(serializers.ModelSerializer):
class Meta:
model = Document
fields = ['id', 'file', 'uploaded_at']
经过多个项目的实践验证,DRF确实是最稳定高效的Python API框架之一。它的学习曲线平缓,但功能强大,非常适合中小型项目的快速开发。对于更复杂的场景,DRF的扩展性也能很好地满足需求。
