Python Django REST Framework实战:构建RESTful API
·
Python Django REST Framework实战:构建RESTful API
引言
在Python Web开发中,Django REST Framework(DRF)是构建RESTful API的首选框架。作为一名从Rust转向Python的后端开发者,我深刻体会到DRF在快速构建高质量API方面的优势。DRF提供了强大的序列化器、视图和认证系统,使得API开发变得更加高效。
DRF核心概念
什么是Django REST Framework
Django REST Framework是基于Django的RESTful API框架,具有以下特点:
- 序列化器:将模型数据转换为JSON格式
- 视图集:提供CRUD操作的统一接口
- 认证系统:支持多种认证方式
- 权限控制:细粒度的权限管理
- 分页支持:内置分页功能
架构设计
┌─────────────────────────────────────────────────────────────┐
│ DRF 架构层次 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 路由层 │───▶│ 视图层 │───▶│ 序列化层 │ │
│ │ (URL Router) │ │ (ViewSet) │ │ (Serializer) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 数据层 (Model) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
环境搭建与基础配置
安装依赖
pip install django djangorestframework
项目配置
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'myapp',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
序列化器实战
基本序列化器
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email', 'is_active']
class UserCreateSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ['username', 'email', 'password']
def create(self, validated_data):
user = User.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['password']
)
return user
嵌套序列化器
from rest_framework import serializers
from .models import Post, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ['id', 'content', 'created_at']
class PostSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True, read_only=True)
author_name = serializers.CharField(source='author.username', read_only=True)
class Meta:
model = Post
fields = ['id', 'title', 'content', 'author_name', 'comments', 'created_at']
视图集实战
基本视图集
from rest_framework import viewsets
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def get_queryset(self):
queryset = super().get_queryset()
username = self.request.query_params.get('username')
if username:
queryset = queryset.filter(username__icontains=username)
return queryset
自定义视图集
from rest_framework import viewsets, status
from rest_framework.response import Response
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ViewSet):
def list(self, request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
post = Post.objects.get(pk=pk)
serializer = PostSerializer(post)
return Response(serializer.data)
def create(self, request):
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save(author=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
路由配置
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSet, PostViewSet
router = DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'posts', PostViewSet)
urlpatterns = [
path('api/', include(router.urls)),
]
认证与权限
Token认证
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
}
# urls.py
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
path('api-token-auth/', obtain_auth_token),
]
自定义权限
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.author == request.user
实际业务场景
场景一:博客API
from rest_framework import viewsets, permissions
from .models import Post, Comment
from .serializers import PostSerializer, CommentSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
def get_queryset(self):
post_id = self.request.query_params.get('post_id')
if post_id:
return self.queryset.filter(post_id=post_id)
return self.queryset
场景二:分页配置
from rest_framework.pagination import PageNumberPagination
class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
pagination_class = CustomPagination
性能优化
查询优化
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.select_related('author').prefetch_related('comments').all()
serializer_class = PostSerializer
缓存
from django.core.cache import cache
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def get_stats(request):
cache_key = 'api_stats'
stats = cache.get(cache_key)
if not stats:
stats = calculate_stats()
cache.set(cache_key, stats, 60 * 5)
return Response(stats)
总结
Django REST Framework为Python后端开发者提供了强大的API开发能力。通过序列化器、视图集和认证系统,可以快速构建高质量的RESTful API。从Rust开发者的角度来看,DRF的声明式API设计与Rust的类型安全理念有相似之处。
在实际项目中,建议合理使用视图集和序列化器来提高开发效率,并注意查询优化和缓存来提升性能。
更多推荐



所有评论(0)