From 9027f12792b0747e51a403ad432792f05a90c362 Mon Sep 17 00:00:00 2001 From: erjemin Date: Sat, 21 Mar 2026 15:17:12 +0300 Subject: [PATCH] =?UTF-8?q?mod:=20=D0=BB=D0=B5=D0=BD=D0=B8=D0=B2=D0=BE?= =?UTF-8?q?=D0=B5=20=D1=84=D0=BE=D1=80=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D0=B3=D0=BE=D0=B2=20(=D1=87?= =?UTF-8?q?=D1=82=D0=BE=D0=B1=D1=8B=20=D0=B2=20=D0=BF=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B5=20=D1=83=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BD=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D1=83=20=D0=BD?= =?UTF-8?q?=D0=B0=20gunicorn)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dicquo/web/admin.py | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/dicquo/web/admin.py b/dicquo/web/admin.py index f0ea411..493c202 100644 --- a/dicquo/web/admin.py +++ b/dicquo/web/admin.py @@ -8,6 +8,7 @@ from taggit.models import Tag from taggit.utils import parse_tags from django.db import models from django.db.utils import OperationalError, ProgrammingError +from django.utils.functional import lazy try: from etpgrf.typograph import Typographer @@ -35,13 +36,35 @@ class TagSelect2Widget(Select2TagWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + # Определяем функцию, которая будет выполнена лениво. + def get_choices_safely(): + try: + # list() материализует ленивый QuerySet, что важно для lazy() + return list(Tag.objects.values_list('name', 'name')) + except (OperationalError, ProgrammingError): + # Если таблицы нет (например, при collectstatic), возвращаем пустой список. + return [] + # lazy() не выполняет функцию сразу, а создает "обещание" (promise), + lazy_safe_choices = lazy(get_choices_safely, list) # choices: список всех существующих тегов по имени. - # Важно: на этапах вроде collectstatic таблицы taggit ещё может не быть, - # поэтому оборачиваем в try/except и молча игнорируем отсутствие БД. - try: - self.choices = [(t.name, t.name) for t in Tag.objects.all()] - except (OperationalError, ProgrammingError): - self.choices = [] + # Присваиваем ему ленивый объект. + self.choices = lazy_safe_choices() + + # @property + # def choices(self): + # # Этот код будет выполняться только тогда, + # # когда Django реально запросит self.choices для отрисовки. + # # К этому моменту приложение будет полностью готово. + # try: + # self.choices = [(t.name, t.name) for t in Tag.objects.all()] + # except (OperationalError, ProgrammingError): + # self.choices = [] + # + # # Важно: Нам нужно установить setter, даже если он пустой, + # # потому что родительский класс будет пытаться присвоить ему значение. + # @choices.setter + # def choices(self, value): + # pass class Media: css = { @@ -135,7 +158,7 @@ class DictumAdminForm(forms.ModelForm): ) etp_hanging_punctuation = forms.ChoiceField( label="Висячая пунктуация", - choices=[('no', 'Нет'), ('left', 'Слева'), ('right', 'Справа'), ('both', 'Обе стороны')], + choices=[('no', 'Нет'), ('left', 'Слева'), ('right', 'Справа'), ], initial='left', required=False, help_text="Выносить кавычки за границу текстового блока" @@ -144,7 +167,7 @@ class DictumAdminForm(forms.ModelForm): label="Переносы", initial=True, required=False, - help_text="Расставлять мягкие переносы (­)" + help_text="Расставлять мягкие переносы (­)" ) etp_sanitize = forms.BooleanField( label="Санитайзер (HTML)",