Итак, мой сериализатор называется так:
result_serializer = TaskInfoSerializer(tasks, many=True)
И сериализатор:
class TaskInfoSerializer(serializers.ModelSerializer):
done_jobs_count = serializers.SerializerMethodField()
total_jobs_count = serializers.SerializerMethodField()
task_status = serializers.SerializerMethodField()
class Meta:
model = Task
fields = ('task_id', 'task_name', 'done_jobs_count', 'total_jobs_count', 'task_status')
def get_done_jobs_count(self, obj):
qs = Job.objects.filter(task__task_id=obj.task_id, done_flag=1)
condition = False
# Some complicate logic to determine condition that I can't reveal due to business
result = qs.count() if condition else 0
# this function take around 3 seconds
return result
def get_total_jobs_count(self, obj):
qs = Job.objects.filter(task__task_id=obj.task_id)
# this query take around 3-5 seconds
return qs.count()
def get_task_status(self, obj):
done_count = self.get_done_jobs_count(obj)
total_count = self.get_total_jobs_count(obj)
if done_count >= total_count:
return 'done'
else:
return 'not yet'
Когда вызывается функция get_task_status, она вызывает другие 2 функции и снова выполняет эти 2 дорогостоящих запроса.
Есть ли лучший способ предотвратить это? И я действительно не знаю порядок вызова этих функций, основан ли он на порядке, объявленном в полях Meta? Или выше этого?
Edit:
Логика в get_done_jobs_count немного усложняется, и я не могу сделать это в одном запросе при получении задачи
Редактировать 2:
Я просто перенести все эти функции в модель и использовать cached_property
https://docs.djangoproject.com/en/2.1/ref/utils/#module-django.utils.functional
Но возникает другой вопрос: надежно ли это число? Я не очень разбираюсь в кеше django, является ли cached_property существующим только для этого экземпляра (только до тех пор, пока API не получит список задач, возвращающих ответ) или он будет существовать какое-то время?