Как аннотировать связанную таблицу в django?
У меня есть две сущности Task
и Technology
. Таблица технологий имеет FK к задаче и каждая задача имеет 9 технологий.
enabled | категория | частота | c1 | c2 | c3 | note |
---|---|---|---|---|---|---|
True | 3G | 2100 | 11/03/2010 | foo | ||
Ложь | 4G | 700 | 02/04/2012 | bam | ||
Ложь | 4G | 1800 | спам | |||
True | 4G | 2100 | bim | |||
True | 4G | 2600 | альбом | |||
True | 5G | 700 | тан | |||
Ложь | 5G | 3700 | тан | |||
True | 5G | 26000 | tan |
Для каждой задачи мне нужно аннотировать ячейку этой технологической матрицы. Это означает аннотировать что-то вроде:
- candidates_technologies__3G_2100_enabled
- кандидаты_технологии__3G_2100_c1
- кандидаты_технологии__3G_2100_c2
- кандидаты_технологии__3G_2100_c3
- кандидаты_технологии__3G_2100_заметка
- кандидаты_технологии__4G_700_включено
- candidates_technologies__4G_700_c1
- candidates_technologies__4G_700_c2
- candidates_technologies__4G_700_c3
- кандидаты_технологии__4G_700_заметка
- candidates_technologies__4G_1800_enabled
- candidates_technologies__4G_1800_c1
- candidates_technologies__4G_1800_c2
- candidates_technologies__4G_1800_c3
- кандидаты_технологии__4G_1800_заметка
- ...
Где candidates_technologies
- связанное имя. В настоящее время это мое решение, но оно убивает производительность.
from django.db.models import Q, F, Value, Case, When, DateField, BooleanField, CharField
bool_cols, text_cols = ["enabled"], ["onair_note"]
date_cols = [t for t in TECHNOLOGY_COLUMNS if t not in text_cols or t not in bool_cols]
columns = date_cols + bool_cols + date_cols
def _get_output_field(col):
if col in bool_cols:
return False, BooleanField()
elif col in text_cols:
return "", CharField()
else:
return None, DateField()
tech_annotations, whens = {}, []
for category, frequency in TECHNOLOGY_FREQUENCY_LIST:
for column in columns:
out = _get_output_field(column)
key = '_'.join([category, frequency, column])
value = ExpressionWrapper(
Case(
When(
Q(**{'candidates_technologies__category': category}) &
Q(**{'candidates_technologies__frequency': frequency}),
then=F('candidates_technologies__{}'.format(column)),
),
default=Value(out[0]),
output_field=out[1]
),
output_field=out[1]
)
tech_annotations[key] = value
Знаете ли вы, как превратить матрицу / таблицу в аннотированные поля?