Как оптимизировать запрос к БД? Объясню логику: есть модель в которой находяться поля: логин пользователя (это поле имеет связь с моделью user, где находятся все пользователи) и несколько полей с показателями этого пользователя. Данные для заполнения БД парсятся отдельной функцией из xlsx файла, функция возвращает список словарей, где ключ это название показателя, а значение сам показатель. После этого в цикле формируется другой список, в который вносятся значения с последующим сохранением в БД.
Проблема в том, что при каждой итерации происходит обращение к БД для получения объекта логина пользователя. Из-за чего выполнение занимает очень много времени.
Предполагаю, что процесс можно оптимизировать так: сначала получить все логины пользователя, а потом, при формировании списка для сохранения в БД брать логины из уже полученного запроса. Однако не совсем понимаю как это сделать.
Функция которая парсит файл:
import openpyxl
class ImportFile:
def __init__(self, filename, type="xlsx"):
self.filename = filename
self.type = type
self.wb = None
if self.type == "xlsx":
self.wb = openpyxl.load_workbook(filename=filename, data_only=True)
def import_file_kpi_base_normative(self, **kwargs):
"""Парсит файл 'КПЭ Базовый норматив'"""
if self.wb is None:
return []
ws = self.wb["Лист1"]
max_row = ws.max_row + 1
data_for_return = []
start_line = 4
for row in range(start_line, max_row):
_row = ws[row]
data_for_return.append(
{
"login": _row[10].value,
"plan_KVC": _row[17].value,
"fact_KVC": _row[21].value,
"plan_FZ_PU": _row[24].value,
"fact_FZ_PU": _row[25].value,
"plan_halva": _row[28].value,
"fact_halva": _row[29].value,
"plan_loyal": _row[32].value,
"fact_loyal": _row[33].value,
}
)
return data_for_return
Функция которая сохраняет значения в БД:
@admin.register(models.KPIBaseNormative)
class KPIBaseNormativeAdmin(ImportXslxAdminMixin, admin.ModelAdmin):
readonly_fields = (
'profile', 'plan_KVC', 'fact_KVC', 'plan_FZ_PU', 'fact_FZ_PU', 'plan_halva', 'fact_halva', 'plan_loyal', 'fact_loyal', 'update_date', )
def load_file_xls_handler(self, request):
file = request.FILES['file'].read()
try:
exporter = ImportFile(BytesIO(file))
data = exporter.import_file_kpi_base_normative()
except:
self.message_user(request, 'Файл xslx не соответствует формату', messages.ERROR)
return redirect('../load_file_xls_page')
models.KPIBaseNormative.objects.all().delete()
object = []
for row in data:
try:
object.append(
models.KPIBaseNormative(
profile=Profile.objects.get(user__username=row["login"]), plan_KVC=int(row['plan_KVC']), fact_KVC=int(row['fact_KVC']), plan_FZ_PU=int(row['plan_FZ_PU']), fact_FZ_PU=int(row['fact_FZ_PU']), plan_halva=int(row['plan_halva']), fact_halva=int(row['fact_halva']), plan_loyal=int(row['plan_loyal']), fact_loyal=int(row['fact_loyal']), )
)
except Profile.DoesNotExist:
continue models.KPIBaseNormative.objects.bulk_create(object)
return super(KPIBaseNormativeAdmin, self).load_file_xls_handler(request)