在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']
现有代码问题分析
- 错误使用
get_queryset方法:该方法用于定义视图的基础查询集,不适合处理添加请求的业务逻辑,应使用create方法或自定义action。 get_or_create参数错误:模型中关联课程的字段是courses,而非my_courses(my_courses是反向关联名称);且id=pk逻辑错误,pk应为目标课程的ID,而非MyCoursesList记录的ID。- 冗余循环遍历:无需遍历用户所有收藏课程,直接通过
user和course_id即可判断是否已收藏。 - 异常处理不规范:宽泛的
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)
关键逻辑说明
- 参数校验:先检查课程ID是否传入,避免空值错误。
- 收藏状态校验:通过
filter(user=user, courses_id=course_id).exists()快速判断课程是否已被收藏,性能优于遍历查询。 - 课程存在性校验:确保要添加的课程本身存在,避免无效关联。
- 合理关联字段:创建收藏记录时,从课程对象中获取teacher信息(替代原代码的默认值1),保证数据准确性。
- 规范响应:根据不同场景返回对应HTTP状态码和清晰的提示信息,符合RESTful规范。
内容的提问来源于stack exchange,提问作者Ashti Nematian
相关产品推荐
相关产品推荐

