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

在Django API视图中实现课程收藏前的对象存在性校验

课程收藏功能:校验与添加逻辑修正

需求描述

开发课程收藏列表功能,用户可将目标课程添加至收藏列表。添加前需校验:若课程已在用户收藏列表中,返回提示信息;若不存在,则完成添加操作。

现有代码实现

视图代码

class AddtoMyCoursesView(viewsets.GenericViewSet):
    serializer_class = MyCoursesListSerializer

    def get_queryset(self, *args, **kwargs):
        pk = self.request.POST.get('pk')
        user = self.request.user
        print(user)
        courses = MyCoursesList.objects.filter(user=user.pk)
        print(courses)
        for course in courses:
            print(course)
            try:
                return MyCoursesList.objects.get_or_create(my_courses=course, id=pk)
            except:
                return Response("Item already exists", status.HTTP_400_BAD_REQUEST)

模型代码

class MyCoursesList(models.Model):
    user = models.ForeignKey('accounts.User', on_delete=models.CASCADE, blank=True)
    courses = models.ForeignKey(Courses, on_delete=models.CASCADE, blank=True,related_name='my_courses')
    added_date = models.DateTimeField(auto_now_add=True)
    teacher = models.ForeignKey(Teacher, on_delete=models.DO_NOTHING, default=1)

序列化器代码

class MyCoursesListSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyCoursesList
        fields = ['id', 'user', 'courses', 'added_date', 'teacher']

现有代码问题分析

  1. 错误使用get_queryset方法:该方法用于定义视图的基础查询集,不适合处理添加请求的业务逻辑,应使用create方法或自定义action。
  2. get_or_create参数错误:模型中关联课程的字段是courses,而非my_courses(my_courses是反向关联名称);且id=pk逻辑错误,pk应为目标课程的ID,而非MyCoursesList记录的ID。
  3. 冗余循环遍历:无需遍历用户所有收藏课程,直接通过user和course_id即可判断是否已收藏。
  4. 异常处理不规范:宽泛的except会捕获所有异常,无法精准处理已存在的情况;且get_queryset不应返回Response对象。

修正后的代码实现

视图代码(优化版)

from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin

class AddtoMyCoursesView(GenericViewSet, CreateModelMixin):
    serializer_class = MyCoursesListSerializer
    queryset = MyCoursesList.objects.all()

    def create(self, request, *args, **kwargs):
        # 获取要添加的课程ID
        course_id = request.data.get('pk')
        if not course_id:
            return Response({"error": "课程ID不能为空"}, status=status.HTTP_400_BAD_REQUEST)
        
        user = request.user
        # 检查用户是否已收藏该课程
        exists = MyCoursesList.objects.filter(user=user, courses_id=course_id).exists()
        if exists:
            return Response({"message": "该课程已在收藏列表中"}, status=status.HTTP_400_BAD_REQUEST)
        
        # 验证课程是否存在
        try:
            course = Courses.objects.get(pk=course_id)
        except Courses.DoesNotExist:
            return Response({"error": "指定课程不存在"}, status=status.HTTP_404_NOT_FOUND)
        
        # 创建收藏记录,从课程对象关联teacher(替代原默认值1,保证数据准确)
        my_course = MyCoursesList.objects.create(
            user=user,
            courses=course,
            teacher=course.teacher  # 假设Course模型含teacher字段,可根据实际调整
        )
        serializer = self.get_serializer(my_course)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

关键逻辑说明

  1. 参数校验:先检查课程ID是否传入,避免空值错误。
  2. 收藏状态校验:通过filter(user=user, courses_id=course_id).exists()快速判断课程是否已被收藏,性能优于遍历查询。
  3. 课程存在性校验:确保要添加的课程本身存在,避免无效关联。
  4. 合理关联字段:创建收藏记录时,从课程对象中获取teacher信息(替代原代码的默认值1),保证数据准确性。
  5. 规范响应:根据不同场景返回对应HTTP状态码和清晰的提示信息,符合RESTful规范。

内容的提问来源于stack exchange,提问作者Ashti Nematian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:25:54