mod: рефакторинг "каталог типовых проёмов"
This commit is contained in:
@@ -1,82 +1,99 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.db.models import F
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from oknardia.models import (
|
||||
Seria_Info,
|
||||
Win_MountDim,
|
||||
)
|
||||
from oknardia.models import MountDim2Apartment
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||||
from web.add_func import get_flaps_for_mini_pictures
|
||||
import time
|
||||
import pytils
|
||||
from typing import Any
|
||||
from itertools import groupby
|
||||
from operator import itemgetter
|
||||
|
||||
def standard_opening(request: HttpRequest) -> HttpResponse:
|
||||
time_start = time.perf_counter()
|
||||
to_template: dict[str, object] = {} # словарь, для передачи шаблону
|
||||
q_seria = Seria_Info.objects.raw('SELECT oknardia_seria_info.id, oknardia_seria_info.sName '
|
||||
'FROM oknardia_seria_info '
|
||||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||||
'ORDER BY oknardia_seria_info.sName;')
|
||||
to_template.update({'SERIAS': list(q_seria)})
|
||||
q_win_opening = Win_MountDim.objects.raw(
|
||||
'SELECT oknardia_win_mountdim.*,'
|
||||
' oknardia_seria_info.sName,'
|
||||
' oknardia_seria_info.id AS ID_Seria '
|
||||
'FROM oknardia_win_mountdim'
|
||||
' INNER JOIN oknardia_mountdim2apartment'
|
||||
' ON oknardia_win_mountdim.id = oknardia_mountdim2apartment.kMountDim_id'
|
||||
' RIGHT OUTER JOIN oknardia_apartment_type'
|
||||
' ON oknardia_apartment_type.id = oknardia_mountdim2apartment.kApartment_id'
|
||||
' RIGHT OUTER JOIN oknardia_seria_info'
|
||||
' ON oknardia_apartment_type.kSeria_id = oknardia_seria_info.id '
|
||||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||||
'GROUP BY oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,'
|
||||
' oknardia_win_mountdim.bIsDoor, oknardia_win_mountdim.bIsNearDoor,'
|
||||
' oknardia_win_mountdim.sFlapConfig, oknardia_win_mountdim.id,'
|
||||
' oknardia_seria_info.sName, oknardia_seria_info.id '
|
||||
'ORDER BY oknardia_win_mountdim.iWinWidth DESC,'
|
||||
' oknardia_win_mountdim.iWinHight DESC,'
|
||||
' oknardia_win_mountdim.bIsNearDoor,'
|
||||
' oknardia_win_mountdim.bIsDoor,'
|
||||
' oknardia_win_mountdim.id,'
|
||||
' oknardia_seria_info.sName;')
|
||||
list_windows_opening = []
|
||||
tmp_id = 0
|
||||
for i in q_win_opening:
|
||||
if tmp_id != i.id:
|
||||
tmp_id = i.id
|
||||
image_file_name = get_flaps_for_mini_pictures(i.sFlapConfig)
|
||||
list_windows_opening.append({
|
||||
"ID": i.id,
|
||||
"INCLUDING_IN_SERIA": [{
|
||||
"ID": i.ID_Seria,
|
||||
"NAME_T": pytils.translit.slugify(i.sName),
|
||||
"NAME": i.sName
|
||||
}],
|
||||
"INCLUDING_IN_SERIA_ID": [],
|
||||
"URL2IMG": image_file_name,
|
||||
"FLAP_CONFIG": i.sFlapConfig,
|
||||
"DESCRIPTION": i.sDescripion.split(" для")[0].split(" (")[0],
|
||||
"DESCRIPTION_L": i.sDescripion,
|
||||
"IS_DOOR": i.bIsDoor,
|
||||
"IS_NEAR_DOOR": i.bIsNearDoor,
|
||||
"H": i.iWinHight * 10,
|
||||
"W": i.iWinWidth * 10
|
||||
})
|
||||
else:
|
||||
list_windows_opening[-1]["INCLUDING_IN_SERIA"].append({
|
||||
"ID": i.ID_Seria,
|
||||
"NAME_T": pytils.translit.slugify(i.sName),
|
||||
"NAME": i.sName
|
||||
})
|
||||
|
||||
def _make_slug(value: str) -> str:
|
||||
"""Транслитерирует строку в slug (pytils)."""
|
||||
return pytils.translit.slugify(value)
|
||||
|
||||
|
||||
def _append_visit_context(to_template: dict, request: HttpRequest, time_start: float) -> None:
|
||||
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
|
||||
to_template.update({
|
||||
'LIST_WIN_OPENING': list_windows_opening,
|
||||
# получаем последние визиты клиента через куки
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
# получаем последние визиты всех посетителей из базы
|
||||
# id2log, log_visit = get_last_all_user_visit_list()
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start)
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
})
|
||||
return render(request, "catalog/catalog_standard_opening.html", to_template)
|
||||
|
||||
|
||||
def standard_opening(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
Каталог стандартных оконных проёмов и балконных блоков.
|
||||
|
||||
Что делает вьюха:
|
||||
- Собирает уникальные пары «проём ↔ серия» через ORM.
|
||||
- Агрегирует данные для шаблона в структуру LIST_WIN_OPENING с помощью groupby.
|
||||
- Добавляет в контекст последние визиты и время выполнения.
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
|
||||
q_win_opening = (
|
||||
MountDim2Apartment.objects.filter(kApartment__kSeria_id=F('kApartment__kSeria__kRoot_id'))
|
||||
.values(
|
||||
'kMountDim_id',
|
||||
'kMountDim__sFlapConfig',
|
||||
'kMountDim__sDescripion',
|
||||
'kMountDim__bIsDoor',
|
||||
'kMountDim__bIsNearDoor',
|
||||
'kMountDim__iWinHight',
|
||||
'kMountDim__iWinWidth',
|
||||
'kApartment__kSeria_id',
|
||||
'kApartment__kSeria__sName',
|
||||
)
|
||||
.distinct()
|
||||
.order_by(
|
||||
'-kMountDim__iWinWidth',
|
||||
'-kMountDim__iWinHight',
|
||||
'kMountDim__bIsNearDoor',
|
||||
'kMountDim__bIsDoor',
|
||||
'kMountDim_id',
|
||||
'kApartment__kSeria__sName',
|
||||
)
|
||||
)
|
||||
|
||||
list_windows_opening: list[dict[str, Any]] = []
|
||||
# Группируем результаты по ID проёма, чтобы собрать все серии, в которые он входит.
|
||||
# `order_by` в запросе гарантирует, что все записи для одного проёма идут подряд.
|
||||
for mount_dim_id, group in groupby(q_win_opening, key=itemgetter('kMountDim_id')):
|
||||
rows_for_opening = list(group)
|
||||
first_row = rows_for_opening[0]
|
||||
description_full = first_row['kMountDim__sDescripion'] or ''
|
||||
|
||||
# Собираем список серий для текущего проёма.
|
||||
serias_for_opening = [
|
||||
{
|
||||
'ID': row['kApartment__kSeria_id'],
|
||||
'NAME_T': _make_slug(row['kApartment__kSeria__sName']),
|
||||
'NAME': row['kApartment__kSeria__sName'],
|
||||
}
|
||||
for row in rows_for_opening
|
||||
]
|
||||
# Формируем данные для строки таблиц (типовой проем)
|
||||
list_windows_opening.append({
|
||||
'ID': mount_dim_id,
|
||||
'INCLUDING_IN_SERIA': serias_for_opening,
|
||||
'URL2IMG': get_flaps_for_mini_pictures(first_row['kMountDim__sFlapConfig']),
|
||||
'FLAP_CONFIG': first_row['kMountDim__sFlapConfig'],
|
||||
'DESCRIPTION': description_full.split(' для')[0].split(' (')[0],
|
||||
'DESCRIPTION_L': description_full,
|
||||
'IS_DOOR': first_row['kMountDim__bIsDoor'],
|
||||
'IS_NEAR_DOOR': first_row['kMountDim__bIsNearDoor'],
|
||||
'H': first_row['kMountDim__iWinHight'] * 10, # см -> мм
|
||||
'W': first_row['kMountDim__iWinWidth'] * 10, # см -> мм
|
||||
})
|
||||
|
||||
to_template = {'LIST_WIN_OPENING': list_windows_opening}
|
||||
_append_visit_context(to_template, request, time_start)
|
||||
return render(request, 'catalog/catalog_standard_opening.html', to_template)
|
||||
|
||||
Reference in New Issue
Block a user