add: management-команда regenerate_seria_prerender для оффлайн пересборки pre-render шаблонов серий; обновлены SETUP.md, README.md, MANAGEMENT_RUNBOOK.md
This commit is contained in:
@@ -14,7 +14,7 @@ from oknardia.models import (
|
||||
Building_Info,
|
||||
)
|
||||
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_big_pictures, touch_reload_wsgi
|
||||
from web.add_func import get_flaps_for_big_pictures
|
||||
import time
|
||||
import os
|
||||
import math
|
||||
@@ -217,7 +217,6 @@ def catalog_seria_info(
|
||||
string_prerender = render_to_string("seria_info/all_seria_info_pre_light.html", to_template)
|
||||
with open(light_template_w_path, "w", encoding="utf-8") as file:
|
||||
file.write(string_prerender)
|
||||
touch_reload_wsgi(light_template_w_path)
|
||||
else:
|
||||
to_template.update({"THIS_SERIA_NAME": q_seria.sName})
|
||||
|
||||
@@ -346,7 +345,7 @@ def seria_info_geo_code(seria_id: int | str = DEFAULT_SERIA_ID_FOR_CATALOG) -> d
|
||||
жилые/муниципальные/государственные площади, число жителей, квартир,
|
||||
лицевых счетов и диапазон показателя состояния домов.
|
||||
|
||||
:param seria_id: int | str -- id серии, для которой нужно получить данные
|
||||
:param seria_id: int | str -- id серии, для которой нужно получить данные.
|
||||
:return: dict -- {
|
||||
"DATA4GEO": [...],
|
||||
"MUNICIPAL_M2": ...,
|
||||
|
||||
113
oknardia/web/management/commands/regenerate_seria_prerender.py
Normal file
113
oknardia/web/management/commands/regenerate_seria_prerender.py
Normal file
@@ -0,0 +1,113 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytils
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db.models import F
|
||||
from django.test import RequestFactory
|
||||
|
||||
from oknardia.models import Seria_Info
|
||||
from web import catalog_series
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Пересоздает pre-render шаблоны для страниц серий (/catalog/seria/.../all<ID>)."""
|
||||
|
||||
help = "Пересоздает pre-render шаблоны catalog_seria_info для выбранных или всех корневых серий."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--seria-id",
|
||||
type=int,
|
||||
action="append",
|
||||
default=[],
|
||||
help="ID серии (можно передавать несколько раз). По умолчанию пересоздаются все корневые серии.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Пересоздать даже если pre-render файл уже существует.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Только показать, что будет сделано, без генерации файлов.",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
seria_ids: list[int] = options["seria_id"]
|
||||
force: bool = options["force"]
|
||||
dry_run: bool = options["dry_run"]
|
||||
|
||||
# Берем только корневые серии, потому что для них строятся канонические URL /all<ID>.
|
||||
query = Seria_Info.objects.filter(id=F("kRoot_id")).only("id", "sName").order_by("id")
|
||||
if seria_ids:
|
||||
query = query.filter(id__in=seria_ids)
|
||||
|
||||
targets = list(query)
|
||||
if not targets:
|
||||
raise CommandError("Не найдено подходящих корневых серий для пересоздания pre-render.")
|
||||
|
||||
templates_root = Path(settings.TEMPLATES[0]["DIRS"][0])
|
||||
prepared_dir = templates_root / settings.PATH_FOR_SERIA_INFO_HTML_INCLUDE
|
||||
prepared_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
request_factory = RequestFactory()
|
||||
created = 0
|
||||
planned = 0
|
||||
skipped = 0
|
||||
|
||||
for seria in targets:
|
||||
target_file = prepared_dir / f"{seria.id}_id.html"
|
||||
if target_file.exists() and not force:
|
||||
skipped += 1
|
||||
self.stdout.write(f"SKIP {seria.id}: {target_file}")
|
||||
continue
|
||||
|
||||
if dry_run:
|
||||
action = "REGEN" if target_file.exists() else "CREATE"
|
||||
self.stdout.write(f"{action} {seria.id}: {target_file}")
|
||||
planned += 1
|
||||
continue
|
||||
|
||||
if target_file.exists():
|
||||
target_file.unlink()
|
||||
|
||||
slug = pytils.translit.slugify(seria.sName)
|
||||
request = request_factory.get(f"/catalog/seria/{slug}/all{seria.id}")
|
||||
|
||||
# В команде принудительно включаем «production-mode» для вьюхи,
|
||||
# чтобы она прошла тяжелую ветку и пересоздала pre-render файл.
|
||||
old_debug = catalog_series.DEBUG
|
||||
try:
|
||||
catalog_series.DEBUG = False
|
||||
response = catalog_series.catalog_seria_info(request, slug, seria.id)
|
||||
finally:
|
||||
catalog_series.DEBUG = old_debug
|
||||
|
||||
if response.status_code != 200:
|
||||
raise CommandError(
|
||||
f"Серия {seria.id}: ожидался status=200, получен {response.status_code}."
|
||||
)
|
||||
if not target_file.exists():
|
||||
raise CommandError(f"Серия {seria.id}: pre-render файл не создан: {target_file}")
|
||||
|
||||
created += 1
|
||||
self.stdout.write(self.style.SUCCESS(f"OK {seria.id}: {target_file}"))
|
||||
|
||||
if dry_run:
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"DRY-RUN. Обработано: {len(targets)}. Будет создано/пересоздано: {planned}. Пропущено: {skipped}."
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Готово. Обработано: {len(targets)}. Создано/пересоздано: {created}. Пропущено: {skipped}."
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user