如何在DRF通用列表视图中新增用户课程订阅状态的自定义字段
实现方案
1. 标准规范写法
遵循DRF分层设计原则,在序列化器中新增自定义字段,视图层仅负责数据查询逻辑,无需重写list方法:
序列化器修改
from rest_framework import serializers from .models import Course class CourseSerializer(serializers.ModelSerializer): # 新增只读的订阅状态布尔字段 is_subscribed = serializers.BooleanField(read_only=True) class Meta: model = Course # 此处替换为你原本定义的字段列表,新增`is_subscribed`即可 fields = ['id', 'name', 'desc', 'is_subscribed']
视图层修改
使用Django的Exists子查询一次性注解所有课程的订阅状态,完全避免N+1查询问题:
from django.db.models import Exists, OuterRef from rest_framework import generics from rest_framework.permissions import IsAuthenticated from .models import Course, Subscription from .serializers import CourseSerializer class CourseListView(generics.ListAPIView): permission_classes = [IsAuthenticated, ] serializer_class = CourseSerializer def get_queryset(self): current_user = self.request.user # 构造订阅状态子查询 sub_query = Subscription.objects.filter( user=current_user, course=OuterRef('pk') ) # 一次性给所有课程增加订阅状态注解 return Course.objects.annotate( is_subscribed=Exists(sub_query) )
方案说明
- 符合DRF开发规范:序列化层负责字段输出逻辑,视图层负责数据获取逻辑,逻辑解耦易维护
- 性能最优:仅执行1次数据库查询即可拿到所有课程和对应用户的订阅状态,没有额外查询开销
- 代码简洁:无需重写
list方法,也不需要手动遍历构造序列化结果
内容的提问来源于stack exchange,提问作者AlwaysLearning
相关产品推荐
相关产品推荐

