Доступ к методам класса в шаблонах Jinja2 - PullRequest
0 голосов
/ 01 октября 2018

Я использую приложение Flask в бэкэнде, которое должно отображать список кодов SKU (Stock Keeping Unit) во внешнем интерфейсе, используя цикл внутри шаблона Jinja2.Класс SKU выглядит следующим образом:

class SKU:
"""Class to hold SKU data returned from the database."""

def __init__(self, sku, scanned_at, actual_count, expected_count):
    """Initialize the SKU class with relevant attributes."""
    self.sku = str(sku)
    self.scanned_at = str(scanned_at)
    self.actual_count = int(actual_count)
    self.expected_count = int(expected_count)

def get_progress(self):
    """Get the SKU production progress as a percentage."""
    return ((self.actual_count / self.expected_count) *
            100 if self.expected_count != 0 else 0)

У меня есть метод get_all_skus_today(), который возвращает все строки в базе данных за сегодняшнюю дату в виде списка SKU объектов.Я хочу сделать это, когда кто-то обращается к /skus по следующему маршруту:

@app.route("/skus")
def skus():
    """Get all SKUs for the day and render the skus.html template."""
    skus = get_all_skus_today()
    return render_template("skus.html", skus=skus)

Проблема в том, что я хочу показать значение прогресса, то есть возвращение функции get_progress(), котораяне атрибут класса, а метод.Я хочу сделать что-то вроде этого:

{% for sku_row in skus %}
    {{ sku_row.sku }}
    {{ sku_row.get_progress }}
{% endfor %}

Но это не работает.Я хочу избежать необходимости циклически перебирать список объектов SKU и преобразовывать их в кортеж, чтобы затем передавать его в функцию render_template (что я и делал раньше).

Любая помощь очень ценится - пустьЯ знаю, если вам нужны дальнейшие разъяснения.

1 Ответ

0 голосов
/ 01 октября 2018

Вы можете создать дополнительный класс для загрузки и обработки информации из базы данных и создать список Sku объектов:

import sqlite3
class _Sku:
   def __init__(self, row):
     self.__dict__ = dict(zip(row, ['_sku', 'scanned_at', 'actual_count', 'expected_count']))
   @property
   def sku(self):
      return str(self._sku)
   @property
   def get_progress(self):
     return ((int(self.actual_count) / int(self.expected_count)) *
        100 if int(self.expected_count) != 0 else 0)

class Sku:
  def __init__(self, _listing):
    self.all_vals = [_Sku(i) for i in _listing]
  def __iter__(self):
    yield from self.all_vals
  @classmethod
  def create_skus(cls, _filename='somefilename.db'):
    #if so desired, you can replace query below with your own
    return cls(sqlite3.connect(_filename).cursor().execute("SELECT scanned, actual, expected FROM skus"))

Затем в приложении:

@app.route("/skus")
def skus():
  """Get all SKUs for the day and render the skus.html template."""
   return render_template("skus.html", skus=Sku.create_skus())

Теперь приведенный выше код позволит использовать ваш оригинальный шаблон:

{% for sku_row in skus %}
   {{ sku_row.sku }}
   {{ sku_row.get_progress }}
{% endfor %}
...