将字段添加到 DRF 通用列表视图
Add a field to DRF generic list view
我需要创建一个 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 轻松做到这一点:
只需更改您视图中的查询集:
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__'
我需要创建一个 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 轻松做到这一点:
只需更改您视图中的查询集:
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__'