python - 从 SerializerMethodField() 更改为 annotate()
问题描述
我是 django 和 django-rest-framework 的新手,我遇到了一个需要优化 API 端点的项目。发现 SerializerMethodField() 导致对 SQL 的重复查询,我认为这是 N+1 问题。我目前正在阅读并尝试探索 annotate(),但发现逻辑计算很复杂,我被困在如何将其转换为 annotate() 上。有没有人知道如何正确实施这一点?请看下面的代码。希望任何人都可以指导我,因为我已经被困了好几天了。非常感谢。
序列化程序.py:
class BootcampClassStatisticsSerializer(ModelBaseSerializer):
attendance_rating = serializers.SerializerMethodField()
def get_attendance_rating(self, instance):
attendance_rating = None
attendance_count = 0
present_count = 0
bootcampers = instance.bootcamper_set.all()
date = self.context.get('date')
for bootcamper in bootcampers:
attendances = bootcamper.dailyattendance_set.all()
if date:
attendances = attendances.filter(date=date)
present_attendances = attendances.filter(status=constants.PRESENT)
if instance.class_type == constants.DAY:
attendance_count += len(attendances) * 2
for item in present_attendances:
if item.duration == 'wd':
present_count += 2
if item.duration == 'hd':
present_count += 1
if instance.class_type == constants.NIGHT:
attendance_count += len(attendances)
present_count += len(present_attendances)
if attendance_count:
attendance_rating = round(present_count / attendance_count * 100, 2)
return attendance_rating
class Meta:
model = BootcampClass
fields = (
'id',
'batch_number',
'start_date',
'end_date',
'class_type',
'attendance_rating'
视图.py:
class BootcampClassStatisticsList(APIView):
queryset = BootcampClass.objects.all()
serializer = BootcampClassStatisticsSerializer()
return Response(serializer, status=status.HTTP_200_OK)
解决方案
推荐阅读
- java - java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“RecyclerView$ViewHolder.shouldIgnore()”
- nginx - 如何使用 nginx 将语言查询重写为对 SEO 更友好的 URL?
- javascript - 如果文本区域中写入了某个单词,则替换 url
- python - AttributeError:无法设置属性,
- mysql - 将已排序分区中的行划分为特定数量的组。[MySQL]
- mysql - 警告:1265 第 1 行的“价格”列的数据被截断
- javascript - 如何将项目推送到作为数组的 es6 Map 对象值中?
- php - FPDF 无法通过 sql 连接加载 PDF 文档
- javascript - javascript中链接方法的复杂性
- excel - 如何将数据粘贴到右侧的下一个空单元格中?