# 39. 通过Django Rest Framework构建RESTful API: 实战项目开发
## 一、Django Rest Framework(DRF)环境配置与初始化
### 1.1 创建Django项目与DRF集成
我们将从创建Python虚拟环境开始,使用以下命令初始化项目:
# 创建项目目录
mkdir bookstore-api && cd bookstore-api
# 设置虚拟环境
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate.bat # Windows
# 安装核心依赖
pip install django djangorestframework
通过Django-admin创建新项目和应用:
django-admin startproject config .
python manage.py startapp books
在settings.py中添加必要配置:
INSTALLED_APPS = [
...
'rest_framework',
'books.apps.BooksConfig'
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20
}
### 1.2 数据库模型设计
我们以图书管理系统为例设计数据模型:
# books/models.py
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
birth_date = models.DateField()
bio = models.TextField()
class Book(models.Model):
GENRE_CHOICES = [
('FIC', '小说'),
('NON', '非虚构'),
('SCI', '科技'),
]
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
isbn = models.CharField(max_length=13, unique=True)
publish_date = models.DateField()
genre = models.CharField(max_length=3, choices=GENRE_CHOICES)
price = models.DecimalField(max_digits=6, decimal_places=2)
该模型设计遵循数据库规范化原则,通过外键关联作者信息,使用选择字段限定图书类型。ISBN字段设置唯一约束确保数据完整性。
## 二、DRF核心组件开发实践
### 2.1 序列化器(Serializer)深度解析
序列化器是DRF的数据转换核心,我们创建两个序列化器:
# books/serializers.py
from rest_framework import serializers
from .models import Book, Author
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'name', 'birth_date']
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only=True)
class Meta:
model = Book
fields = '__all__'
extra_kwargs = {
'isbn': {'validators': []} # 禁用默认唯一性验证
}
def validate_price(self, value):
if value < 0:
raise serializers.ValidationError("价格不能为负数")
return value
该实现演示了嵌套序列化、字段验证和元数据控制等关键功能。通过自定义validate_price方法实现业务逻辑验证。
### 2.2 视图(View)与路由(Router)配置
使用DRF的视图集简化开发:
# books/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.select_related('author')
serializer_class = BookSerializer
filterset_fields = ['genre', 'author__name']
search_fields = ['title', 'isbn']
配置路由系统:
# config/urls.py
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from books import views
router = DefaultRouter()
router.register(r'books', views.BookViewSet)
urlpatterns = [
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls')),
]
这种配置方式自动生成标准REST端点,包含GET/POST/PUT/PATCH/DELETE方法,支持过滤和搜索功能。
## 三、API安全与性能优化
### 3.1 认证与权限控制
实现自定义权限类:
# books/permissions.py
from rest_framework import permissions
class IsStaffOrReadOnly(permissions.BasePermission):
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS:
return True
return request.user and request.user.is_staff
在视图中应用权限:
class BookViewSet(viewsets.ModelViewSet):
permission_classes = [IsStaffOrReadOnly]
# 其他配置保持不变
### 3.2 查询性能优化
通过多种技术提升API响应速度:
1. 使用select_related减少数据库查询次数
2. 添加缓存中间件
3. 实施分页机制
# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379',
}
}
# views.py
class BookViewSet(viewsets.ModelViewSet):
@method_decorator(cache_page(60*15))
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
## 四、API测试与文档生成
### 4.1 自动化测试实现
编写全面的测试用例:
# books/tests.py
from rest_framework.test import APITestCase
from django.contrib.auth.models import User
from .models import Book
class BookAPITestCase(APITestCase):
def setUp(self):
self.admin = User.objects.create_superuser('admin', 'admin@test.com', 'password')
self.book_data = {
'title': 'Python编程从入门到实践',
'isbn': '9787115477679',
# 其他字段数据...
}
def test_create_book(self):
self.client.force_login(self.admin)
response = self.client.post('/api/books/', self.book_data)
self.assertEqual(response.status_code, 201)
self.assertEqual(Book.objects.count(), 1)
### 4.2 API文档生成
使用DRF的Schema生成功能:
# urls.py
from rest_framework.schemas import get_schema_view
schema_view = get_schema_view(
title="Bookstore API",
description="图书管理系统API文档",
version="1.0.0"
)
urlpatterns += [
path('schema/', schema_view),
]
访问/schema/端点可获得OpenAPI规范的文档,可配合Swagger UI使用。
---
**技术标签**:Django Rest Framework RESTfulAPI Python后端开发 API设计 数据库建模 Web服务开发