add: Перерасчет рейтинга перенесен в Django Management Command
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
1. `generate_sitemaps` — оффлайн генерация sitemap-файлов.
|
||||
2. `regenerate_seria_prerender` — оффлайн пересборка pre-render шаблонов для `catalog_seria_info`.
|
||||
3. `populate_seo_fields` — автозаполнение SEO-полей блога из существующих данных.
|
||||
4. `make_rating` — пересчёт рейтингов профилей и стеклопакетов методом Манна-Уитни.
|
||||
|
||||
## Общие правила запуска
|
||||
|
||||
@@ -225,6 +226,238 @@ print(f'Пусто sMetaKeywords: {posts.filter(sMetaKeywords=\"\").count()}')
|
||||
- ✅ **Откат через SQL** — если нужно очистить, используй: `UPDATE oknardia_blogposts SET sSlug='', sMetaDescription='', sMetaKeywords='';`
|
||||
- ✅ **Всегда используй `--dry-run`** перед первым запуском для проверки.
|
||||
|
||||
## 4) Команда `make_rating`
|
||||
|
||||
Назначение:
|
||||
- пересчитать рейтинги оконных профилей, стеклопакетов и наборов услуг используя метод Манна-Уитни.
|
||||
- сохранить результаты в поля `fProfileRating`, `fGlazingRating`, `fSetRating` (0.0 … 5.0 звёзд).
|
||||
- заполнить JSON-состав рейтинга в поля `sProfileDescription`, `sGlazingDescription`, `sSetDescription`.
|
||||
|
||||
### Базовый запуск
|
||||
|
||||
Пересчитать рейтинги всех профилей и стеклопакетов (стандартный режим):
|
||||
|
||||
```bash
|
||||
cd /Users/e-serg/PRJ/2022-oknardia
|
||||
poetry run python oknardia/manage.py make_rating
|
||||
```
|
||||
|
||||
### Параметры запуска
|
||||
|
||||
**`--verbosity 0`** — минимум информации (только ошибки):
|
||||
**`--verbosity 1`** — стандартная информация (по умолчанию):
|
||||
**`--verbosity 3`** — очень подробный вывод (для отладки, для каждого профиля/стеклопакета таблица):
|
||||
|
||||
Пример использования с параметром `--verbosity`:
|
||||
|
||||
```bash
|
||||
poetry run python oknardia/manage.py make_rating --verbosity 3 | head -500
|
||||
```
|
||||
|
||||
### АЛГОРИТМ: Метод Манна-Уитни (Mann-Whitney U Step Rank)
|
||||
|
||||
Команда использует адаптированный вариант критерия Манна-Уитни для ранжирования параметров качества оконных
|
||||
предложений и комопнентов (профилей, стеклопакетов, наборов услуг) на основе их технических характеристик
|
||||
и популярности у поставщиков.
|
||||
|
||||
#### Как это работает:
|
||||
|
||||
1. **Сортировка объектов** по одному параметру (например, по теплопередаче):
|
||||
- Профиль A: 0.60 Ro → ранг = 0.0
|
||||
- Профиль B: 0.60 Ro → ранг = 0.0 (то же значение, ранг не меняется)
|
||||
- Профиль C: 0.80 Ro → ранг = 1.0 (новое значение, добавляем вес параметра)
|
||||
- Профиль D: 0.95 Ro → ранг = 2.0 (ещё новое значение)
|
||||
|
||||
2. **Направление ранжирования** определяется флагом `revers`:
|
||||
- `revers=False` — **БОЛЬШЕ = ЛУЧШЕ** (например, теплопередача, звукоизоляция)
|
||||
- `revers=True` — **МЕНЬШЕ = ЛУЧШЕ** (например, высота в проёме для прочности)
|
||||
|
||||
3. **Нормализация рангов** к диапазону 0.0 … 1.0:
|
||||
- Профиль A: 0.0 / 2.0 = 0.0
|
||||
- Профиль B: 0.0 / 2.0 = 0.0
|
||||
- Профиль C: 1.0 / 2.0 = 0.5
|
||||
- Профиль D: 2.0 / 2.0 = 1.0
|
||||
|
||||
4. **Суммирование рангов** по всем параметрам:
|
||||
- TmpRating = Σ(ранг_параметра × вес_параметра)
|
||||
|
||||
5. **Преобразование в звёзды** (0.0 … 5.0):
|
||||
- ТmpRating нормализуется к 0..1
|
||||
- Умножается на 5.0 для получения финального рейтинга
|
||||
|
||||
#### Пример итогового рейтинга профиля:
|
||||
|
||||
```
|
||||
Профиль "Brusbox Super Aero"
|
||||
Теплопередача: 0.60 Ro (ранг 0.9, вес 1.0)
|
||||
Звукоизоляция: 33 дБ (ранг 0.8, вес 1.0)
|
||||
Высота в проёме: 112 мм (ранг 0.6, вес 0.3)
|
||||
Количество камер: 6 шт (ранг 0.7, вес 0.1)
|
||||
|
||||
Итого: (0.9×1.0 + 0.8×1.0 + 0.6×0.3 + 0.7×0.1) / 2.3 ≈ 3.8 звёзд ⭐⭐⭐⭐
|
||||
```
|
||||
|
||||
### ПРОФИЛИ: какие параметры учитываются
|
||||
|
||||
| № | Параметр | Поле БД | ЛУЧШЕ | Вес | Описание |
|
||||
|---|----------------------|----------------------------|--------------------|-----|-----------------------------------------------------|
|
||||
| 1 | Звукоизоляция | `fProfileSoundproofing` | БОЛЬШЕ дБ | 1.0 | Сопротивление шуму (дБ) |
|
||||
| 2 | Теплопередача | `fProfileHeatTransf` | БОЛЬШЕ Ro | 1.0 | Сопротивление теплопередаче (м²×°C/Вт) |
|
||||
| 3 | Высота в проёме | `iProfileHeight` | МЕНЬШЕ мм | 0.3 | Видимая высота в световом проёме (экономия) |
|
||||
| 4 | Высота фальца | `iProfileRabbet` | БОЛЬШЕ мм | 0.2 | Глубина фальца для герметизации |
|
||||
| 5 | Толщина стеклопакета | `iProfileGlazingThickness` | БОЛЬШЕ мм | 0.2 | Максимальная толщина стеклопакета |
|
||||
| 6 | Толщина профиля | `iProfileThickness` | БОЛЬШЕ мм | 0.2 | Монтажная (боковая) ширина профиля |
|
||||
| 7 | Контуры уплотнения | `fProfileSeals` | БОЛЬШЕ контуров | 1.2 | Количество контуров уплотнения |
|
||||
| 8 | Количество камер | `iProfileCameras` | БОЛЬШЕ шт | 0.1 | Число камер в профиле (из рамки + створки) |
|
||||
| 9 | Популярность | `NumOffer` | БОЛЬШЕ предложений | 0.1 | Используется ли профиль в коммерческих предложениях |
|
||||
|
||||
**Примеры интерпретации:**
|
||||
- Профиль с рейтингом **5.0 ⭐⭐⭐⭐⭐**: отличная теплопередача + звукоизоляция + много камер + многоконтурные
|
||||
уплотнения.
|
||||
- Профиль с рейтингом **2.0 ⭐⭐**: среднее качество, слабые характеристики.
|
||||
- Профиль с рейтингом **0.5 ⭐**: слабые характеристики или производить не предоставил данных и их нет в отрытых источниках.
|
||||
|
||||
### СТЕКЛОПАКЕТЫ: какие параметры учитываются
|
||||
|
||||
| № | Параметр | Поле БД | ЛУЧШЕ | Вес | Описание |
|
||||
|---|-------------------|-----------------------------|--------------|------|----------------------------------------------------------------------------------------|
|
||||
| 1 | Звукоизоляция | `fGlazingSoundproofing` | БОЛЬШЕ дБ | 1.0 | Звукоизоляционный коэффициент (дБ) |
|
||||
| 2 | Теплопередача | `fGlazingHeatTransfer` | БОЛЬШЕ Ro | 1.0 | Сопротивление теплопередаче (м²×°C/Вт) |
|
||||
| 3 | Светопропускание | `fGlazingLightTransmission` | БОЛЬШЕ % | 0.25 | Коэффициент пропускания видимого света (%), отражение света снаружи |
|
||||
| 4 | Солнцепропускание | `fGlazingPassingSun` | **МЕНЬШЕ %** | 0.15 | Коэффициент солнечного излучения (SHGC) — В России меньше = лучше для охлаждения летом |
|
||||
| 5 | Толщина | `iGlazingThickness` | БОЛЬШЕ мм | 0.1 | Общая толщина стеклопакета |
|
||||
| 6 | Количество камер | `iGlazingCamerasN` | БОЛЬШЕ шт | 0.1 | Число воздушных/аргоновых камер |
|
||||
|
||||
**Особенности стеклопакетов:**
|
||||
- **Светопропускание** = как много естественного света проходит в помещение (больше = лучше)
|
||||
- **Солнцепропускание** = как много солнечного тепла/излучения проходит (в России: меньше = лучше, потому что внутри есть отражающее напыление)
|
||||
- Двухкамерный (с аргоном) почти всегда лучше однокамерного
|
||||
- Трёхкамерные = премиум для холодного климата
|
||||
|
||||
**Примеры интерпретации:**
|
||||
- **5.0 ⭐⭐⭐⭐⭐**: трёхкамерный с хорошей теплопередачей, звукоизоляцией (обычно с аргоном и напылением).
|
||||
- **3.0 ⭐⭐⭐**: двухкамерный, среднее качество
|
||||
- **1.0 ⭐**: однокамерный старого образца или с плохими характеристиками
|
||||
|
||||
### Когда запускать
|
||||
|
||||
- **После первого развертывания** — заполнить рейтинги всех профилей и стеклопакетов.
|
||||
- **После изменения каталога** (добавление нового профиля/стеклопакета).
|
||||
- **После уточнения характеристик** (например, поставщик предоставил новые данные).
|
||||
```bash
|
||||
poetry run python oknardia/manage.py make_rating
|
||||
```
|
||||
|
||||
- **По расписанию** (например, ежемесячно, чтобы пересчитать популярность):
|
||||
```bash
|
||||
30 2 * * 1 cd /Users/e-serg/PRJ/2022-oknardia && poetry run python oknardia/manage.py make_rating >> /var/log/oknardia-rating.log 2>&1
|
||||
```
|
||||
- **После обновления весов** в `settings.py` (константы `RANK_PVCP_*`, `RANK_GLAZ_*`).
|
||||
|
||||
### Откат и безопасность
|
||||
|
||||
- **Безопасна для повторного запуска** — пересчитывает все рейтинги заново.
|
||||
- **Всегда обновляет только рейтинги** — другие данные в таблицах не меняются.
|
||||
- **Откат через SQL** — если нужно вернуть старые значения (перед запуском рекомендуется бэкап):
|
||||
```sql
|
||||
-- Очистить рейтинги профилей
|
||||
UPDATE oknardia_pvcprofiles SET fProfileRating = 0.0, sProfileDescription = '{}';
|
||||
|
||||
-- Очистить рейтинги стеклопакетов
|
||||
UPDATE oknardia_glazing SET fGlazingRating = 0.0, sGlazingDescription = '{}';
|
||||
```
|
||||
|
||||
### Примеры из реальных данных
|
||||
|
||||
Пример вывода `--verbosity 1`:
|
||||
|
||||
```
|
||||
=== НАЧАЛИ ПЕРЕСЧЁТ РЕЙТИНГОВ ===
|
||||
|
||||
========================================
|
||||
[ЭТАП 1]: Пересчёт рейтингов ПРОФИЛЕЙ...
|
||||
========================================
|
||||
|
||||
✓ Обнулены рейтинги у 94 профилей
|
||||
✓ Найдено 94 профилей для ранжирования
|
||||
✓ Сохранено 94 профилей с финальными рейтингами
|
||||
|
||||
=============================================
|
||||
[ЭТАП 2]: Пересчёт рейтингов СТЕКЛОПАКЕТОВ...
|
||||
=============================================
|
||||
|
||||
✓ Обнулены рейтинги у 97 стеклопакетов
|
||||
✓ Найдено 97 стеклопакетов для ранжирования
|
||||
✓ Сохранено 97 стеклопакетов с финальными рейтингами
|
||||
|
||||
[OK!] ПЕРЕСЧЁТ РЕЙТИНГОВ ЗАВЕРШЁН УСПЕШНО!
|
||||
• Обновлено профилей: 94
|
||||
• Обновлено стеклопакетов: 97
|
||||
```
|
||||
|
||||
Пример вывода `--verbosity 3` (наиболее подробный):
|
||||
|
||||
```
|
||||
=== НАЧАЛИ ПЕРЕСЧЁТ РЕЙТИНГОВ ===
|
||||
|
||||
========================================
|
||||
[ЭТАП 1]: Пересчёт рейтингов ПРОФИЛЕЙ...
|
||||
========================================
|
||||
|
||||
✓ Обнулены рейтинги у 94 профилей
|
||||
✓ Найдено 94 профилей для ранжирования
|
||||
...
|
||||
...
|
||||
====================================================================================================
|
||||
ПРОФИЛЬ: politech W80 (ID: 78)
|
||||
====================================================================================================
|
||||
Характеристика Значение Ранг (0..1) Вклад
|
||||
----------------------------------------------------------------------------------------------------
|
||||
Высота в проёме 120 мм 0.368 *
|
||||
Популярность 0 предл. 0.000
|
||||
Теплопередача 0.91 Ro 0.657 ***
|
||||
Толщина профиля 80 мм 0.588 **
|
||||
Толщина стеклопакета 42 мм 0.409 **
|
||||
Уплотнители 3 контуров 1.000 *****
|
||||
Фальц 14 мм 0.150
|
||||
Число камер 12 шт 0.714 ***
|
||||
Шумоизоляция 44.00 дБ 0.909 ****
|
||||
----------------------------------------------------------------------------------------------------
|
||||
ИТОГО: Рейтинг = 4.94/5.0 ****
|
||||
...
|
||||
...
|
||||
✓ Сохранено 94 профилей с финальными рейтингами
|
||||
|
||||
=============================================
|
||||
[ЭТАП 2]: Пересчёт рейтингов СТЕКЛОПАКЕТОВ...
|
||||
=============================================
|
||||
|
||||
✓ Обнулены рейтинги у 97 стеклопакетов
|
||||
✓ Найдено 97 стеклопакетов для ранжирования
|
||||
...
|
||||
...
|
||||
====================================================================================================
|
||||
СТЕКЛОПАКЕТ: Однокамерный 5-4, 25 мм (И+аргон) (ID: 60) | Марка:СПО 5М1-Ar16-И4
|
||||
====================================================================================================
|
||||
Характеристика Значение Ранг (0..1) Вклад
|
||||
----------------------------------------------------------------------------------------------------
|
||||
Камеры — 0.000
|
||||
Светопропускание 74.00% 0.824 ****
|
||||
Солнцепропускание 58.00% 0.450 **
|
||||
Теплопередача 0.91 Ro 0.936 ****
|
||||
Толщина 25 мм 0.400 **
|
||||
Шумоизоляция — 0.429 **
|
||||
----------------------------------------------------------------------------------------------------
|
||||
ИТОГО: Рейтинг = 4.87/5.0 ****
|
||||
...
|
||||
...
|
||||
✓ Сохранено 97 стеклопакетов с финальными рейтингами
|
||||
|
||||
[OK!] ПЕРЕСЧЁТ РЕЙТИНГОВ ЗАВЕРШЁН УСПЕШНО!
|
||||
• Обновлено профилей: 94
|
||||
• Обновлено стеклопакетов: 97
|
||||
```
|
||||
|
||||
## Оркестрация и reload веб-сервера
|
||||
|
||||
Важно:
|
||||
@@ -276,9 +509,7 @@ poetry run python oknardia/manage.py check
|
||||
- все тяжелые и административные операции переносить из HTTP в management-команды;
|
||||
- `/service/*` оставлять только как thin UI/мониторинг или убрать полностью.
|
||||
|
||||
Кандидаты на перенос:
|
||||
- действия из `service.py` (`/service/make_rating`, sitemap/служебные задачи и т.п.);
|
||||
- любые операции, которые могут идти дольше обычного web-request.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user