Я новичок в django -rest-framework, и у меня есть проект, в котором мне нужно оптимизировать время отклика существующей конечной точки API. Используя django -debug-toolbar, нашел несколько способов использования prefetch_related () для уменьшения количества запросов SQL. Проблема в том, что я обнаружил, что дизайн сериализатора должен иметь несколько SerializerMethodField для получения значений статистики, а использование prefetch_related работает только для all (), но во втором поле метода сериализатора с filter () все еще запрашивается для каждого класса l oop. Вы можете увидеть образец кода ниже (это не код спецификаций c, а что-то вроде этого).
serializer.py:
class ClassStatisticsSerializer(ModelBaseSerializer):
total_sessions = serializers.SerializerMethodField()
activity_count = serializers.SerializerMethodField()
def get_total_sessions(self, instance):
sessions = instance.classactivity_set.all()
date = self.context.get('date')
if date:
sessions = sessions.filter(date=date)
if len(sessions) == 0:
return None
return sessions.count()
def get_activity_count(self, instance):
activities = instance.classactivity_set.filter(is_present=False)
date = self.context.get('date')
if date:
activities = activities.filter(date=date)
if len(activities) == 0:
return None
return activities.count()
class Meta:
model = Class
fields = (
'id',
'batch',
'type,
'total_sessions'
'activity_count'
)
views.py:
class ClassStatisticsList(APIView):
def get(self, request, *args, **kwargs):
queryset = Class.objects.all().prefetch_related('classactivity_set')
serializer = ClassStatisticsSerializer()
return Response(serializer, status=status.HTTP_200_OK)
Здесь, когда я проверяю запросы SQL на панели инструментов отладки django, get_total_sessions был запрошен один раз на SQL, но get_activity_count не был, поскольку это еще один запрос запроса на SQL и запрашивается для каждого класса l oop. На данный момент о создании новой модели не может быть и речи, поэтому я застрял на том, как правильно выполнить предварительную выборку второго запроса. Надеюсь, вы сможете предложить возможный способ решения этой проблемы. Заранее спасибо, ребята.