如何将Django课程内容增改视图转换为DRF API视图?
Django REST Framework 实现课程内容增改API视图方案
1. 定义序列化器
序列化器对应原视图里的ModelForm,负责模型数据与JSON格式的转换,为每个内容类型分别定义:
from rest_framework import serializers from .models import Text, Video, Image, File class TextSerializer(serializers.ModelSerializer): class Meta: model = Text exclude = ['owner', 'order', 'created', 'updated'] class VideoSerializer(serializers.ModelSerializer): class Meta: model = Video exclude = ['owner', 'order', 'created', 'updated'] class ImageSerializer(serializers.ModelSerializer): class Meta: model = Image exclude = ['owner', 'order', 'created', 'updated'] class FileSerializer(serializers.ModelSerializer): class Meta: model = File exclude = ['owner', 'order', 'created', 'updated'] # 做个映射字典,方便动态获取对应序列化器 SERIALIZER_MAP = { 'text': TextSerializer, 'video': VideoSerializer, 'image': ImageSerializer, 'file': FileSerializer }
2. 自定义权限控制
确保只有课程所有者能操作对应模块的内容,编写权限类:
from rest_framework import permissions class IsCourseOwner(permissions.BasePermission): def has_object_permission(self, request, view, obj): # 验证当前用户是模块所属课程的所有者 return obj.course.owner == request.user
3. 编写API视图类
继承DRF的APIView,对应原视图的业务逻辑,改成API风格实现:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from django.apps import apps from django.shortcuts import get_object_or_404 from rest_framework import permissions from .models import Module, Content class ContentCreateUpdateAPIView(APIView): permission_classes = [permissions.IsAuthenticated, IsCourseOwner] module = None model = None obj = None serializer_class = None def get_model(self, model_name): if model_name in ['text', 'video', 'image', 'file']: return apps.get_model(app_label='courses', model_name=model_name) return None def get_serializer_class(self, model_name): return SERIALIZER_MAP.get(model_name) def dispatch(self, request, module_id, model_name, id=None): # 获取目标模块,权限类会自动验证用户是否为课程所有者 self.module = get_object_or_404(Module, id=module_id) # 动态匹配内容模型 self.model = self.get_model(model_name) if not self.model: return Response({'error': '无效的内容类型'}, status=status.HTTP_400_BAD_REQUEST) # 获取对应序列化器 self.serializer_class = self.get_serializer_class(model_name) if not self.serializer_class: return Response({'error': '无效的内容类型'}, status=status.HTTP_400_BAD_REQUEST) # 若为更新操作,获取待修改的内容对象 if id: self.obj = get_object_or_404(self.model, id=id, owner=request.user) return super().dispatch(request, module_id, model_name, id) def get(self, request, module_id, model_name, id=None): # 返回表单初始化数据,对应原视图的GET请求逻辑 serializer = self.serializer_class(instance=self.obj) return Response({ 'form_data': serializer.data, 'object': serializer.data }) def post(self, request, module_id, model_name, id=None): # 处理内容创建或更新请求 serializer = self.serializer_class( instance=self.obj, data=request.data, files=request.FILES ) if serializer.is_valid(): obj = serializer.save(commit=False) obj.owner = request.user obj.save() # 新创建内容时,关联到目标模块 if not id: Content.objects.create(module=self.module, item=obj) # 根据操作类型返回对应状态码 status_code = status.HTTP_201_CREATED if not id else status.HTTP_200_OK return Response(serializer.data, status=status_code) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
4. 配置API路由
在项目的urls.py中添加API路由:
from django.urls import path from .views import ContentCreateUpdateAPIView urlpatterns = [ # 其他路由... path('api/modules/<int:module_id>/content/<str:model_name>/', ContentCreateUpdateAPIView.as_view(), name='api_content_create'), path('api/modules/<int:module_id>/content/<str:model_name>/<int:id>/', ContentCreateUpdateAPIView.as_view(), name='api_content_update'), ]
关键说明
- 文件上传:前端需要发送
multipart/form-data类型的请求,DRF会自动处理request.FILES中的文件数据 - 权限验证:
IsAuthenticated确保用户已登录,IsCourseOwner确保只有课程所有者能操作对应模块的内容 - 动态匹配:通过
model_name参数动态关联模型与序列化器,和原视图逻辑保持一致 - 响应格式:返回标准JSON数据,方便React前端处理表单渲染和状态更新
内容的提问来源于stack exchange,提问作者Jecop Obad
相关产品推荐
相关产品推荐

