Ищем способ объявить устаревшими переменные в шаблонах Jinja, не нарушая при этом обратную совместимость. PoC создал класс-оболочку. Концепция работает, но многие коды неэффективны.
Предпосылки
Я работаю над большой системой, написанной на Python с использованием Шаблоны Flask и Jinja. Существуют сотни представлений, предоставляющих тысячи переменных контекста, отображаемых в шаблонах Jinja. Существуют также тысячи шаблонов, разбросанных по многим реализациям нашей системы. Конечно, там есть структура, но нет четкого способа узнать, какая реализация или какие шаблоны используют какую контекстную переменную.
С течением времени мы пометили многие переменные как устаревшие. Чтобы не нарушать обратную совместимость, это делается либо жестким кодированием переменной None, либо пустой строкой. Если бы мы действительно удалили переменную, рендеринг шаблонов был бы нарушен. Просмотр всех шаблонов, их изменение и развертывание – это трудоемкий и чреватый ошибками способ.
Проверка концепции
Меня не интересует, когда создаются экземпляры устаревших переменных (что происходит в представлениях), но я хочу знать, когда они фактически используются в шаблоне. «Используется» может означать много вещей в этом контексте, поскольку контекстные переменные могут быть практически любым «простым» объектом Python, например str, int, float, Decimal, list, dict и т. д. Таким образом, «использование» может означать:
- выполненные вычисления (шаблоны, реализующие бизнес-логику с целыми числами). , десятичные дроби, числа с плавающей запятой)
- Проверяется на существование или истинность
- Интерполируется в шаблоне (простая строковая операция)
- Элементы переменной, к которым осуществляется доступ
- и т. д.
Код: Выделить всё
class DeprecatedContextVariable:
def __init__(self, name, value):
self.name = name
self.value = value
def log(self):
logger.warning(f'Deprecated context variable used: {self.name}')
def __str__(self):
self.log()
return f'{self.value}'
def __bool__(self):
self.log()
return bool(self.value)
def __iter__(self):
self.log()
return iter(self.value)
def __add__(self, other):
self.log()
return self.value + other
def __sub__(self, other):
self.log()
return self.value - other
def __radd__(self, other):
self.log()
return self.value + other
def __rsub__(self, other):
self.log()
return other - self.value
# Old usage
from flask import render_template
context = {
'name': 'foo',
'age': 32
'preferences': {
'darkmode': True
}
}
render_template('my-template.html', **context)
# New usage
context = {
'name': 'foo',
'age': DeprecatedContextVariable('age', 32)
'preferences': DeprecatedContextVariable('preferences', {
'darkmode': True
})
}
render_template('my-template.html', **context)
Каковы мои варианты? Есть ли функция Flask или Jinja или внутренняя функция Python, которую я мог бы использовать, или сторонняя библиотека? Имеет ли смысл использовать базовый класс для известных и наиболее используемых типов (
Код: Выделить всё
str
Подробнее здесь: https://stackoverflow.com/questions/790 ... k-jinja-py