Django. Правильный способ получения и передачи сложных данных в шаблон
Моя проблема заключается в том, что мне нужно вывести данные из моделей Report и Plan в эту таблицу в шаблоне введите описание изображения здесь Это календарь, который выводит данные из Отчетов и Планов в правильные ячейки по их .дате (строки) и .машине (столбцы).
То, как я это делаю... отстой. Время загрузки безумное из-за количества запросов по daterange в get_shifts_tables() и код нечитабельный. Но я не могу придумать альтернативу.
Вот он.
views.py
@login_required(login_url="login_user")
@allowed_user_roles(["ADMIN", "MODERATOR"])
def stats(request):
leftovers = get_leftovers()
orders = Order.objects.all().order_by("-id")
order_entries_leftovers = {}
for order_entry in OrderEntry.objects.all():
order_entries_leftovers[order_entry.id] = order_entry.quantity
for report_entry in ReportEntry.objects.filter(report__order=order_entry.order):
order_entries_leftovers[order_entry.id] -= report_entry.quantity
current_date = Table.objects.all()[0].current_date
today = now()
today = today - datetime.timedelta(days=6)
today = today.replace(hour=current_date.hour % 12, minute=current_date.minute,
second=current_date.second, microsecond=current_date.microsecond)
Table.objects.all().update(current_date=today)
active_step_pk, machines, table = get_shifts_table()
context = {
"orders": orders,
"leftovers": leftovers,
"order_entries_leftovers": order_entries_leftovers,
"steps": Step.objects.all(),
"active_step_pk": active_step_pk,
"machines": machines,
"table": table
}
return render(request, "core/stats.html", context)
get_shifts_table() - из scripts.py
def get_shifts_table(
shifts_count=28):
from_date = Table.objects.all()[0].current_date
step = Table.objects.all()[0].current_step
table = []
timestamps = [
from_date + datetime.timedelta(
hours=12 * i) for i in range(0, shifts_count)]
machines = Machine.objects.filter(step=step)
for i in range(len(timestamps) - 1):
row_report_entries = ReportEntry.objects.filter(
report__date__range=(timestamps[i], timestamps[i + 1]),
report__step=step)
if timestamps[i].hour < 12:
txt = str(timestamps[i].strftime("%d.%m")) + " день"
txt = str(timestamps[i].strftime("%d.%m"))
cls = "day"
else:
txt = str(timestamps[i].strftime("%d.%m")) + " ночь"
txt = str(timestamps[i].strftime("%d.%m"))
cls = "night"
row = [{
"class": cls,
"text": txt
}]
for machine in machines:
report_entries = row_report_entries.filter(machine=machine)
if report_entries:
cell = {"class": "done", "report_entries": []}
for report_entry in report_entries:
d = {
"pk": report_entry.pk,
"detail": report_entry.detail,
"quantity": report_entry.quantity,
}
cell["report_entries"].append(d)
row.append(cell)
else:
plan, created = Plan.objects.get_or_create(
machine=machine,
date=timestamps[i],
step=step,
)
cell = {
"class": "plan",
"plan": plan,
}
row.append(cell)
table.append(row)
return step.pk, machines, table
Шаблон таблицы partial
<tbody>
{% for row in table %}
<tr>
{% for cell in row %}
{% if cell.text %}
<td class="{{ cell.class }}">
<div>
{{ cell.text }}
<br/>
{% if cell.class == 'day' %}
<i class="bi bi-sun-fill"></i>
{% else %}
<i class="bi bi-moon-stars-fill"></i>
{% endif %}
</div>
</td>
{% elif cell.plan %}
<td class="{{ cell.class }}"
hx-trigger="click"
hx-get='{% url 'plan_modal' %}'
hx-target="#modals-here"
hx-vals='{"pk": {{ cell.plan.pk }}}'
data-bs-toggle="modal"
data-bs-target="#modals-here">
{% for plan_entry in cell.plan.planentry_set.all %}
<div class={{ plan_entry.detail|get_detail_class }}>
<div class="detail-name">
{{ plan_entry.detail }}
</div>
<div class="quantity">
{{ plan_entry.quantity }}
</div>
</div>
{% endfor %}
</td>
{% else %}
<td class="{{ cell.class }}">
{% for report_entry in cell.report_entries %}
<div class="{{ report_entry.detail|get_detail_class }}"
hx-trigger="click"
hx-get='{% url 'report_modal' %}'
hx-target="#modals-here"
hx-vals='{"pk": {{ report_entry.pk }}}'
data-bs-toggle="modal"
data-bs-target="#modals-here">
{{ report_entry.report }}
<div class="detail-name">
{{ report_entry.detail }}
</div>
<div class="quantity">
{{ report_entry.quantity }}
</div>
</div>
{% endfor %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
Я думал о том, чтобы иметь модель Shift, которая связана с date_range и машиной, но это не кажется правильным и ничего не ускорит.
Возможно, некоторые @свойства в моделях или тегах шаблонов или что-то еще могут исправить это, но я не знаю, каким образом