Знаете ли вы пользовательский тег для увеличения значения в шаблоне Django? - PullRequest
0 голосов
/ 13 октября 2010

Одна очень неприятная вещь со строгим MVC - это то, что вы можете выполнять наименьшую обработку в шаблоне.Хотя обычно это хорошая практика, в этом случае это мешает:

  • Я создаю цикл for для набора запросов большого количества объектов и отображаю некоторые атрибуты;
  • Атрибутыявляются свойствами, делает тяжелую обработку (я не хочу запускать их дважды).
  • В конце мне нужно отобразить итоговое значение этих атрибутов.

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

На данном этапе проекта это небольшое делоПроизводительность - это еще не проблема.Но я действительно хотел бы знать, есть ли решение для этого.

Мой лучший выбор - написать тег шаблона, который выполняет эту работу, но это такая рутинная работа :-) Знаете ли вы кого-нибудь, кто бы сделалэто уже?

EG:

Идеально, это может быть что-то вроде:

{% for object in object_list %}
    - {% sum_in_and_print object.property total %}
{% endfor %}
total {{ total }}

, которое будет отображать:

- 2
- 3
- 1
total 6

Ответы [ 6 ]

1 голос
/ 14 октября 2010

В качестве альтернативы для вычисления суммы в представлении или шаблоне, как насчет QuerySet.Annotate (total_x = Sum ('x')), чтобы база данных занималась вычислениями?

В сторону: я считаю, что попытка решить реальную проблему иногда оправдывает отсутствие ответа на прямой вопрос, когда нет очевидного ответа.

1 голос
/ 13 октября 2010

Я не понимаю, как это рутина.Проверьте, находится ли переменная назначения в контексте, и если нет, инициализируйте ее с помощью пустого объекта класса первого элемента в списке, затем накапливайте.

0 голосов
/ 13 октября 2010

Есть ли убедительная причина, по которой вы не делаете этого в представлении?

Что может быть проще, чем:

total = sum([o.property for o in object_list])

Даже если ваша цель - использовать дженерики, вы можетевсегда оборачивайте его в функцию представления.

Позвольте мне добавить, что я думаю, что функциональность, которую вы конкретно хотите: выводить переменную и добавлять ее к какой-либо произвольной переменной - это такая уникальная функция, которая абсолютно вам понадобится.написать собственный шаблонный тег для него.

К счастью, это очень просто .

Обновление

Как я уже сказал в вопросесвойство триггера тяжелой обработки.Я не хочу запускать их дважды ...

Так что вы можете попробовать это вместо этого:

rendered_object_list = []
for o in object_list:
    rendered_object_list.append({
        'field1': o.field1,
        'field2': o.field2,
        'property': o.property
    })
total = sum(o['property'] for o in rendered_object_list)

Вы обрабатываете это один раз, в представлении, затем когда вы выводитеэто в шаблоне, это словарь, все в словаре уже обработано.

0 голосов
/ 13 октября 2010

Посмотрите на другую систему шаблонов, как Мако. Mako особенно позволяет запускать полный код Python внутри шаблона.

0 голосов
/ 13 октября 2010

Я не знаю, какой проект вы разрабатываете, но если вам уже требуется, чтобы у пользователей был JavaScript, вы можете проверить плагин jQuery.calculation. Это отличный инструмент для переноса всех глупых вычислений на клиентскую сторону.

0 голосов
/ 13 октября 2010

Мне довольно сложно написать хороший тэг.Вам следует позаботиться, если порядок оценки в порядке (сумма может отображаться над данными).Что вы можете иметь много разделов суммирования (может быть, данные тоже).Вероятно, вам понадобится следующая структура:

{% raport %}
    {% sumup %}
        ...
    {% endsumup %}
    {% data %}
        ...
    {% enddata %}
    {% sumup %}
        ...
    {% endsumup %}
{% endraport %}

РЕДАКТИРОВАТЬ: Кроме того, вам будет трудно разобрать многоуровневую структуру:

{% raport %}
    {% sumup %}
        ...
    {% endsumup %}
    {% data %}
        {% raport %}
            {% sumup %}
                ...
            {% endsumup %}
            {% data %}
                ...
            {% enddata %}
            {% sumup %}
                ...
            {% endsumup %}
        {% endraport %}
    {% enddata %}
    {% sumup %}
        ...
    {% endsumup %}
{% endraport %}
...