我需要创建一个DRF列表视图,该视图显示每个课程以及一个布尔字段,表示请求视图的用户是否订阅了该课程。
课程订阅存储在以下模型中:
class Subscription(models.Model):
user = models.ForeignKey(
CustomUser, related_name='subscriptions', null=False,
on_delete=CASCADE)
course = models.ForeignKey(
Course, related_name='subscriptions', null=False,
on_delete=CASCADE)
class Meta:
ordering = ['course', 'user']
unique_together = [['user', 'course']]
这是我写的观点:
class CourseListView(generics.ListAPIView):
permission_classes = [IsAuthenticated, ]
queryset = Course.objects.all()
serializer_class = CourseSerializer
def isSubscribed(self, request, course):
sub = Subscription.objects.filter(
user=request.user, course=course).first()
return True if sub else False
def list(self, request, format=None):
queryset = Course.objects.all()
serializer = CourseSerializer(queryset, many=True)
return Response(serializer.data)
我正在寻找一种方法来修改list
方法,以便在响应中添加关于request.user
是否订阅了每个课程的信息。
serializer
,这将看起来(在伪代码级别)像这样:
serializer = []
for course in querySet:
course['sub'] = self.isSubscribed(request, course)
serializer.append(CourseSerializer(course))
我怀疑应该有一种更好的(标准的、习惯的、不那么复杂的)方式来在列表视图中添加自定义字段,但是没有找到。此外,我想知道是否有可能避免每门课程的数据库命中。
使用Exists:
可以很容易地做到这一点更改视图中的queryset:
from django.db.models import Exists, OuterRef
class CourseListView(generics.ListAPIView):
permission_classes = [IsAuthenticated, ]
serializer_class = CourseSerializer
def get_queryset(self):
subquery = Subscription.objects.filter(user=request.user, course=OuterRef('id'))
return Course.objects.annotate(sub=Exists(subquery))
并在序列化器中为它添加一个字段:
class CourseSerializer(serializers.ModelSerializer):
sub = serializers.BooleanField(read_only=True)
class Meta:
model = Course
fields = '__all__'