From 3479b31f0ea0d84de2f3cd5203be1090c9fdbeb6 Mon Sep 17 00:00:00 2001 From: erjemin Date: Sun, 26 Apr 2026 14:53:49 +0300 Subject: [PATCH] =?UTF-8?q?mod:=20=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86=D1=8B=20=D1=86=D0=B5=D0=BD=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BE=D0=BA=D0=BD=D0=B0=20(=D0=B2=D1=8C?= =?UTF-8?q?=D1=8E=D1=88=D0=BA=D0=B8,=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE?= =?UTF-8?q?=D0=BD=D1=8B,=20=D1=82=D0=B5=D1=81=D1=82=D1=8B,=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D1=8B=D0=B9=20canonical-=D1=80=D0=BE=D1=83=D1=82=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oknardia/oknardia/settings.py | 4 + oknardia/oknardia/urls.py | 15 +- .../catalog/catalog_standard_opening.html | 4 +- .../price/price_offers_for_one_window.html | 151 +++++- .../price_offers_for_one_window_frame.html | 18 +- .../report/show_big_flap_pictures.html | 2 +- .../seria_info/all_seria_info_pre_light.html | 2 +- .../management/commands/generate_sitemaps.py | 4 +- oknardia/web/prices.py | 491 +++++++++++++----- oknardia/web/test_prices.py | 250 +++++++++ 10 files changed, 777 insertions(+), 164 deletions(-) create mode 100644 oknardia/web/test_prices.py diff --git a/oknardia/oknardia/settings.py b/oknardia/oknardia/settings.py index 4c18e26..20196bc 100644 --- a/oknardia/oknardia/settings.py +++ b/oknardia/oknardia/settings.py @@ -205,8 +205,12 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' CAPTCHA_PUBLIC_KEY = env('CAPTCHA_PUBLIC_KEY', default='') CAPTCHA_PRIVATE_KEY = env('CAPTCHA_PRIVATE_KEY', default='') +# МАГИЧЕСКИЕ ЧИСЛА # если непонятно какая серия выбрана через каталог (finger fix) выбираем серию типового строения: DEFAULT_SERIA_ID_FOR_CATALOG = 843 # СЕРИЯ 1-515/9 -- дом в котором я живу +DEFAULT_WIN_WIDTH_MM = 670 # Ширина типового окна для ID=16 (если не выбрано) +DEFAULT_WIN_HEIGHT_MM = 2160 # Высота типового окна для ID=16 (если не выбрано) +DEFAULT_WIN_ID = 16 # ID типового окна (если не выбрано) # количество коммерческих предложений во фрейме отчета OFFER_PER_FRAME = 5 diff --git a/oknardia/oknardia/urls.py b/oknardia/oknardia/urls.py index 7f12e2c..589d81e 100644 --- a/oknardia/oknardia/urls.py +++ b/oknardia/oknardia/urls.py @@ -62,9 +62,9 @@ urlpatterns = [ re_path(r'^catalog/profile[/*]$', catalog_profiles.catalog_profile), # СПИСОК ВСЕХ ПРОФИЛЕЙ И ПРОИЗВОДИТЕЛЕЙ re_path(r'^catalog/profile/(?P\d+)-(?P\S*)' r'/(?P\d+)-(?P\S*)[/*]$', - catalog_profiles.catalog_profile_model), # КАРТОЧКА ПРОФИЛЯ (ИЛИ ПРОИЗВОДИТЕЛЯ) + catalog_profiles.catalog_profile_model), # СТРАНИЦА ОПИСАНИЯ МОДЕЛИ ПРОФИЛЯ re_path(r'^catalog/profile/(?P\d+)-(?P\S*)[/*]$', - catalog_profiles.catalog_profile_manufacture), + catalog_profiles.catalog_profile_manufacture), # КАРТОЧКА ОПИСАНИЯ ПРОИЗВОДИТЕЛЯ ПРОФИЛЯ # --- --- КАТАЛОГ СЕРИЙ ТИПОВОГО СТРОИТЕЛЬСТВА re_path(r'^catalog/seria[/*]$', catalog_series.catalog_seria), # СПИСОК ВСЕХ СЕРИЙ ЗДАНИЙ re_path(r'^catalog/seria/(?P[^/]*)/all(?P\d+)[/*]$', @@ -75,12 +75,15 @@ urlpatterns = [ # --- --- КАТАЛОГ ПРОИЗВОДИТЕЛЕЙ ОКОН re_path(r'^catalog/company[/*]$', catalog_companies.catalog_company), # СПИСОК ВСЕХ ПРОИЗВОДИТЕЛЕЙ ОКОН re_path(r'^catalog/company/(?P\d+)-(?P\S*)[/*]$', - catalog_companies.catalog_company_detail), # КАРТОЧКА ПРОИЗВОДИТЕЛЯ ОКОН + catalog_companies.catalog_company_detail), # КАРТОЧКА ПРОИЗВОДИТЕЛЯ-УСТНОАЩИКА ОКОН # ЦЕНОВЫЕ ПРЕДЛОЖЕНИЯ - # --- Одиночное окно + # --- ОДИНОЧНОЕ ОКНО + re_path(r'^catalog/standard_opening/price-(?P\d+)x(?P\d+)mm-tip(?P\d+)[/*]$', + prices.report_one_win_price), # КАНОНИЧЕСКИЙ SEO-URL СТРАНИЦЫ ЦЕН ДЛЯ ОДНОГО ПРОЕМА re_path(r'^tsena-odnogo-okna/(?P\d+)x(?P\d+)mm/tip(?P\d+)[/*]$', - prices.report_one_win_price), - re_path(r'^next_price_one_flap_frame/idW(?P\d+)N(?P\d+)\S*$', prices.next_one_win_price), + prices.redirect_one_win_price_legacy), # LEGACY-URL: 301 -> КАНОНИЧЕСКИЙ ПУТЬ + re_path(r'^next_price_one_flap_frame/idW(?P\d+)N(?P\d+)\S*$', + prices.next_one_win_price), # ПОДГРУЖАЕМЫЙ ФРЕЙМ С ЦЕНОВЫМИ ПРЕДЛОЖЕНИЯМИ ДЛЯ ОДНОГО ПРОЕМА # --- Ценовая выдача re_path(r'^(?P\d+)/(?P\d+)/(?P[\s\S]*)$', prices.report_price), # --- Подгружаемый фрейм ценовая выдачи diff --git a/oknardia/templates/catalog/catalog_standard_opening.html b/oknardia/templates/catalog/catalog_standard_opening.html index b9f2cf3..a881ef4 100755 --- a/oknardia/templates/catalog/catalog_standard_opening.html +++ b/oknardia/templates/catalog/catalog_standard_opening.html @@ -70,7 +70,7 @@ CollectionPage + ItemList помогают поисковику понять с "@type": "Thing", "name": "{{ i.DESCRIPTION|escapejs }}", "description": "{{ i.DESCRIPTION_L|escapejs }}", - "url": "{{ request.scheme }}://{{ request.get_host }}/tsena-odnogo-okna/{{ i.W|stringformat:'.0f' }}x{{ i.H|stringformat:'.0f' }}mm/tip{{ i.ID }}", + "url": "{{ request.scheme }}://{{ request.get_host }}/catalog/standard_opening/price-{{ i.W|stringformat:'.0f' }}x{{ i.H|stringformat:'.0f' }}mm-tip{{ i.ID }}", "image": "{{ request.scheme }}://{{ request.get_host }}{% static i.URL2IMG %}", "additionalProperty": [ {"@type": "PropertyValue", "name": "Ширина", "value": "{{ i.W|stringformat:'.0f' }} мм"}, @@ -133,7 +133,7 @@ CollectionPage + ItemList помогают поисковику понять с {% if i.IS_DOOR %}да{% else %}—{% endif %} {{ i.DESCRIPTION }} {% for j in i.INCLUDING_IN_SERIA %}{{ j.NAME }}{% if not forloop.last %}, {% endif %}{% endfor %} - цены + цены {% endfor %} diff --git a/oknardia/templates/price/price_offers_for_one_window.html b/oknardia/templates/price/price_offers_for_one_window.html index 081815c..4edef68 100755 --- a/oknardia/templates/price/price_offers_for_one_window.html +++ b/oknardia/templates/price/price_offers_for_one_window.html @@ -5,11 +5,12 @@ {% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %} +{# SEO блоки дат:#} +{# - Date4Meta: дата публикации (первого появления) — используем дату модификации данных. #} +{# - Last4Meta: дата последнего обновления — будет по умолчанию now из base.html. #} {% block Date4Meta %}{{ META_DATA_PUBLISH|date:"Y-m-d" }}{% endblock %} -{% block Last4Meta %}{{ META_DATA_PUBLISH|date:"Y-m-d" }}{% endblock %} - -{% block Top_JS4 %} +{% block Top_JS4 %}{# Для построения круговой диаграммы #} {% endblock %} +{% block ADD_TO_HEAD %}{% comment %} + JSON-LD микроразметка для поисковых систем (Schema.org): + - BreadcrumbList: хлебные крошки для навигации в поиске + - Organization: информация о бренде/компании + - Product: типовое окно с полной информацией + - Рейтинги и цены берутся из таблицы предложений (price_offers_for_one_window_frame.html) + {% endcomment %}{% endblock %} + {% block Description %}Цены на типовое окно {% for I_WIN_DIM in FLAP_DIM %}{{ I_WIN_DIM.iWinWidth|floatformat:0 }}x{{ I_WIN_DIM.iWinHight|floatformat:0 }} см. для домов серий {% for I in SERIA_FOR_WIN %}{% if forloop.last %} и {% elif forloop.first %}{% else %}, {% endif %}{{ I.sName }}{% endfor %}{% endfor %}.{% endblock %} {% comment %}{% block Description %}Цены на пластиковые окна для серии {{ BASE_SERIA }} ({{ APART }} квартира, {{ ADDRESS }}) :: {% for CurOffer in PRICE_FRAME %}Поставщик: {{ CurOffer.MERCHANT }}; Комплектация: {{ CurOffer.SETS_NAME }}; Цена: {{ CurOffer.FIN_PRICE }}₽ :: {% endfor %}{% endblock %}{% endcomment %} @@ -146,12 +281,14 @@ $(function () { // инициализация и обработка попове
-

Цены на окно {% for I_WIN_DIM in FLAP_DIM %}{{ I_WIN_DIM.iWinWidth_mm|floatformat:0 }}×{{ I_WIN_DIM.iWinHight_mm|floatformat:0 }}{% endfor %} мм. (типовое)

+

Цены на окно {% for I_WIN_DIM in FLAP_DIM %}{{ I_WIN_DIM.iWinWidth_mm|floatformat:0 }}×{{ I_WIN_DIM.iWinHight_mm|floatformat:0 }}{% endfor %} мм. (типовое)

-

Типовой проём {% for I_WIN_DIM in FLAP_DIM %}{{ I_WIN_DIM.iWinWidth|floatformat:1 }}×{{ I_WIN_DIM.iWinHight|floatformat:1 }}{% endfor %} cм. представлен в домах серий: {% for I in SERIA_FOR_WIN %}{% if forloop.last %} и {% elif forloop.first %}{% else %}, {% endif %}{{ I.sName }}{% endfor %}. База «Окнардии» размещено {{ NUM_TOTAL_OFFER_N_WORD }} цен для окон в такой проем (из них в архиве {{ NUM_ARCHIVE_OFFER }}). Предложено {{ NUM_FLAP_VARIATION_IN_WORD }} открывания от {{ NUM_TOTAL_FIRM_N_WORD }}.

+

Типовой проём {% for I_WIN_DIM in FLAP_DIM %}{{ I_WIN_DIM.iWinWidth|floatformat:1 }}×{{ I_WIN_DIM.iWinHight|floatformat:1 }}{% endfor %} cм. представлен в домах серий: {% for I in SERIA_FOR_WIN %}{% if forloop.last %} и {% elif forloop.first %}{% else %}, {% endif %}{{ I.sName }}{% endfor %}. База «Окнардии» размещено {{ NUM_TOTAL_OFFER_N_WORD }} цен для окон в такой проем (из них в архиве {{ NUM_ARCHIVE_OFFER }}). Предложено {{ NUM_FLAP_VARIATION_IN_WORD }} открывания от {{ NUM_TOTAL_FIRM_N_WORD }}.

- {# Микроразмектка: названеи продукта #} + {# Микроразметка: название продукта и марка #} + +
@@ -176,8 +313,6 @@ $(function () { // инициализация и обработка попове

В таблице представлены только цены поставщиков из базы «Окнардия». Клик на названии набора отобразит детальную спецификацию каждого предложения: профиль рамы и створки, схему стеклопакета, фурнитуру, элементы отлива, подоконника, откоса, системы климат-контроля) и сопутствующие услуги. Предложения выводятся блоками. Очередной блок выводится кнопкой «Ещё коммерческие предложения окон» под таблицей. Детальные технические характеристики стеклопакетов, профилей и описание сопутствующих услуг можно посмотреть и сравнить с помощью кнопки «Сравнить выбранные».

- {# Микроразмектка: названеи продукта #} -
diff --git a/oknardia/templates/price/price_offers_for_one_window_frame.html b/oknardia/templates/price/price_offers_for_one_window_frame.html index b9b5c37..c507b27 100755 --- a/oknardia/templates/price/price_offers_for_one_window_frame.html +++ b/oknardia/templates/price/price_offers_for_one_window_frame.html @@ -6,8 +6,8 @@ {% if forloop.first %} {# красивые чекбоксы BEGIN #}
{# красивые чекбоксы END #} - -

{{ CurOffer.MERCHANT }} – {{ CurOffer.SETS_NAME }}

+ +

{{ CurOffer.MERCHANT }} – {{ CurOffer.SETS_NAME }}

■ Профиль: {{ CurOffer.PVC_NAME|safe }} ({{ CurOffer.PVC_MANUFACTURER }}) ■ {{ CurOffer.GLAZING_NAME_B|safe }} ({{ CurOffer.GLAZING_MARK }}) @@ -29,17 +29,15 @@
{{ CurOffer.SETS_DATA_MODIFY|date:"d.M.Y" }} - - + + для оконого набора «{{ CurOffer.SETS_NAME }}» компании «{{ CurOffer.MERCHANT }}» состоит из:{% else %}Рейтинг не присвоен{% endif %}" - data-toggle="popover">рейтинг: {% for Star in CurOffer.SETS_RATING_STARTS %}{% if Star == 0 %}{% else %}{% endif %}{% endfor %} {% if CurOffer.SETS_RATING > -0.1 %} {{ CurOffer.SETS_RATING|stringformat:".2f" }}{% endif %} + data-toggle="popover">рейтинг: {% for Star in CurOffer.SETS_RATING_STARTS %}{% if Star == 0 %}{% else %}{% endif %}{% endfor %} {% if CurOffer.SETS_RATING > -0.1 %}{{ CurOffer.SETS_RATING|stringformat:".2f" }}{% endif %}
- - - {% endif %} @@ -50,10 +48,8 @@ {{ CurOffer.TOTAL|stringformat:".2f"|price_format }} {% if CurOffer.DISCOUNT < 0.1 %}—{% else %}−{{ CurOffer.DISCOUNT|stringformat:".1f" }}%{% endif %} - + Итого: {{ CurOffer.FIN_PRICE|stringformat:".2f"|price_format }}  - - {% if CurOffer.DIM|length == 1 %} diff --git a/oknardia/templates/report/show_big_flap_pictures.html b/oknardia/templates/report/show_big_flap_pictures.html index 417448a..6b7a2e3 100755 --- a/oknardia/templates/report/show_big_flap_pictures.html +++ b/oknardia/templates/report/show_big_flap_pictures.html @@ -6,7 +6,7 @@ {{ I_WIN_DIM.iWinWidth|stringformat:".0f" }}0×{{ I_WIN_DIM.iWinHight|stringformat:".0f" }}0 мм.
{% if not I_WIN_DIM.iQuantity == 0 %} {{ I_WIN_DIM.iQuantity }} шт.{% for I_II in I_WIN_DIM.qStr %}{% endfor %}
{% endif %} {{ I_WIN_DIM.sDescription }}{% if not I_WIN_DIM.iQuantity == 0 %}
- цены только этого типового окна{% endif %} + цены только этого типового окна{% endif %} {% endfor %}{% comment %}