You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:37:51