Оптимальный способ вызова метода модели при итерации большого набора запросов в Django
У меня есть пример модели следующего содержания:
class MyModel(models.Model):
#model fields
def my_model_method_1(self, *args):
#logic for the method. This involves reverse lookup, fk fetching and calculations
def my_model_method_2(self, *args):
#logic for the method. This involves reverse lookup, fk fetching and calculations
Теперь я создаю файл excel, содержащий данные вышеупомянутой модели. Я делаю запрос к модели, используя filter
и values
.
my_model_filter = MyModel.objects.filter(fk_field_1__in=list_of_fk_1_field_ids)
my_model_data = my_model_filter.values(all_fields_here)
my_args = {"start_date": some_start_date, "end_date": some_end_date}
for my_model in my_model_data:
model_id = my_model["id"]
my_model_object = my_model_filter.get(id=my_model_id)
val_1 = my_model_object.my_model_method_1(**my_args)
val_2 = my_model_object.my_model_method_2(**my_args)
# other logic
# the above methods are called again for other calculations.
Затем все данные преобразуются в файл excel. Проблема в том, что вызов и получение этих методов занимает много времени. Фактически, для примерно 10 тыс. экземпляров требуется около 30 минут для создания отчета. Я определил, что больше времени уходит на вызов этих методов. Есть ли способ ускорить вызов этих методов?
Один способ, которым я сократил время
for my_model in my_model_data:
model_id = my_model["id"]
my_model_object = my_model_filter.get(id=my_model_id)
val_1 = my_model_object.my_model_method_1(**my_args)
val_2 = my_model_object.my_model_method_2(**my_args)
my_model["val_1"] = val_1
my_model["val_2"] = val_2
for my_model in my_model_data:
model_id = my_model["id"]
my_model_object = my_model_filter.get(id=my_model_id)
# other logic
# just add the values stored in my_model dict from the previous loop here instead of calling the methods again, in the final data structure that will be returned.
Я не знаю, почему это занимает меньше времени, но время, затраченное на это, составило около 17 минут.
Что я могу сделать, чтобы оптимизировать это?
Приношу свои извинения за то, что не выложил оригинальный код, так как не могу поделиться им из-за авторских прав.