每天40分玩转Django:Django REST框架学习指南
今天我们学习了Django REST框架的三个核心概念:序列化、视图集和路由。通过实际的图书管理系统示例,我们看到了如何将这些概念结合起来构建一个完整的REST API。序列化器负责数据转换和验证视图集提供了标准的CRUD操作路由系统自动生成URL模式怎么样今天的内容还满意吗?
Django REST框架学习指南
一、今日学习内容概览
| 知识模块 | 重点内容 |
|---|---|
| 序列化(Serialization) | 模型序列化、验证器、嵌套序列化 |
| 视图集(ViewSets) | 模型视图集、只读视图集、CRUD操作 |
| 路由(Routing) | 自动URL路由、自定义路由、嵌套路由 |
二、详细内容讲解
1. 序列化(Serialization)
序列化是REST框架最核心的概念之一,它负责将复杂的数据类型(如Django模型实例)转换为Python原生数据类型,以便轻松渲染成JSON、XML等格式。
让我们通过一个实际的例子来理解序列化:
# models.py
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
publication_date = models.DateField()
isbn = models.CharField(max_length=13)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return self.title
现在,让我们为这些模型创建序列化器:
# serializers.py
from rest_framework import serializers
from .models import Author, Book
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'name', 'email', 'created_at']
read_only_fields = ['created_at']
def validate_email(self, value):
"""
自定义邮箱验证
"""
if not value.endswith('@example.com'):
raise serializers.ValidationError("邮箱域名必须是example.com")
return value
class BookSerializer(serializers.ModelSerializer):
author_name = serializers.CharField(source='author.name', read_only=True)
class Meta:
model = Book
fields = ['id', 'title', 'author', 'author_name', 'publication_date',
'isbn', 'price']
def validate_isbn(self, value):
"""
ISBN验证
"""
if len(value) != 13:
raise serializers.ValidationError("ISBN必须是13位")
return value
2. 视图集(ViewSets)
视图集提供了一种将常见的视图逻辑组合在一起的方式。下面是一个完整的视图集示例:
# views.py
from rest_framework import viewsets, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Author, Book
from .serializers import AuthorSerializer, BookSerializer
class AuthorViewSet(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['name', 'email']
@action(detail=True, methods=['get'])
def books(self, request, pk=None):
"""
获取作者的所有图书
"""
author = self.get_object()
books = author.books.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['title', 'isbn']
ordering_fields = ['publication_date', 'price']
def perform_create(self, serializer):
"""
创建图书时的自定义行为
"""
serializer.save()
3. 路由(Routing)
DRF提供了便捷的路由注册方式:
# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import AuthorViewSet, BookViewSet
router = DefaultRouter()
router.register(r'authors', AuthorViewSet)
router.register(r'books', BookViewSet)
urlpatterns = [
path('api/', include(router.urls)),
]
三、实战示例:图书管理系统API
让我们创建一个完整的示例,展示如何将上述所有概念结合起来:
4. 完整的API实现示例
下面是一个完整的实现,包含了高级功能:
# permissions.py
from rest_framework import permissions
class IsAdminOrReadOnly(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
# serializers.py
class AuthorDetailSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True, read_only=True)
class Meta:
model = Author
fields = ['id', 'name', 'email', 'created_at', 'books']
# views.py
from rest_framework.pagination import PageNumberPagination
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
class AuthorViewSet(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
pagination_class = CustomPagination
permission_classes = [IsAdminOrReadOnly]
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['created_at']
search_fields = ['name', 'email']
ordering_fields = ['name', 'created_at']
def get_serializer_class(self):
if self.action == 'retrieve':
return AuthorDetailSerializer
return AuthorSerializer
@action(detail=True, methods=['post'])
def add_book(self, request, pk=None):
author = self.get_object()
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save(author=author)
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
5. API测试
为了确保API的可靠性,我们需要编写测试:
# tests.py
from django.test import TestCase
from rest_framework.test import APIClient
from rest_framework import status
from django.urls import reverse
from .models import Author, Book
class AuthorAPITest(TestCase):
def setUp(self):
self.client = APIClient()
self.author_data = {
'name': 'John Doe',
'email': 'john@example.com'
}
self.author = Author.objects.create(**self.author_data)
def test_get_authors(self):
response = self.client.get(reverse('author-list'))
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data['results']), 1)
def test_create_author(self):
new_author_data = {
'name': 'Jane Doe',
'email': 'jane@example.com'
}
response = self.client.post(
reverse('author-list'),
new_author_data,
format='json'
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Author.objects.count(), 2)
四、最佳实践和注意事项
-
序列化器最佳实践:
- 总是定义
Meta.fields而不是使用__all__ - 对敏感字段使用
read_only_fields - 使用嵌套序列化时注意性能影响
- 总是定义
-
视图集最佳实践:
- 使用适当的权限类
- 实现过滤和分页
- 合理使用
@action装饰器定义额外动作
-
路由最佳实践:
- 使用有意义的URL前缀
- 适当使用API版本控制
- 考虑URL命名空间
五、练习任务
-
实现一个带有以下功能的图书评论系统:
- 评论的CRUD操作
- 评分功能
- 评论嵌套展示
-
为图书管理系统添加以下功能:
- 图书分类功能
- 作者详情页面
- 高级搜索功能
六、性能优化建议
- 使用
select_related()和prefetch_related()优化查询:
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.select_related('author')
# ...
- 使用缓存改善性能:
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
class AuthorViewSet(viewsets.ModelViewSet):
@method_decorator(cache_page(60 * 15)) # 缓存15分钟
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
- 使用适当的分页机制:
from rest_framework.pagination import CursorPagination
class CustomCursorPagination(CursorPagination):
page_size = 30
ordering = '-created_at'
七、调试技巧
-
使用DRF的内置调试工具:
- Browsable API
- coreapi文档生成
- Django Debug Toolbar
-
日志配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'debug.log',
},
},
'loggers': {
'django.request': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
八、总结
今天我们学习了Django REST框架的三个核心概念:序列化、视图集和路由。通过实际的图书管理系统示例,我们看到了如何将这些概念结合起来构建一个完整的REST API。记住以下关键点:
- 序列化器负责数据转换和验证
- 视图集提供了标准的CRUD操作
- 路由系统自动生成URL模式
怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)