Django: DRY принципиально противоречит логическому разделению?

Это похоже на этот вопрос: Как использовать параметры метода в Шаблон Django?

Я понимаю (и согласен с и ценю) основную философию django по отделению бизнес-логики от логики представления.

Однако временами кажется, что СУХОСТЬ затрудняет СУХОСТЬ, а СУХОЙ является практикой еще более серьезной, не так ли?

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

Клянусь, я помню способ сделать это - что-то вроде {% include 'llamas'html' | 2%} но могу ошибаться.

Если да, как я могу сохранить этот шаблон (и навигацию) в СУХОМ состоянии, не нарушая принцип разделения логики?


person jMyles    schedule 19.11.2010    source источник


Ответы (2)


Вместо включения вы также можете расширить общий шаблон, который включает или встраивает код для хлебных крошек.

например sometemplate.html:

{% extends "base_with_breadcrumbs.html" %}

Кроме того, если вы не хотите, чтобы на некоторых страницах были хлебные крошки, внутри «base_with_breadcrumbs.html» вы можете заключить крошки в оператор {% if with_crumbs%} ... {% endif%}.

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

Также обратите внимание на jinja2, он похож на django, но имеет много хороших функций. Я переписал 50 с лишним шаблонов в jinja для своего проекта и никогда не оглядывался назад.

person Evgeny    schedule 19.11.2010

Я бы посоветовал перейти на Jinja2. Тег include в основном такой же, но у вас также есть тег macro, который дает вам вызываемый блок, который можно легко повторно использовать с переменными.

Некоторые варианты тега include:

{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}
{% include ['page_detailed.html', 'page.html'] %}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}

С помощью макросов вы можете делать такие вещи:

{% macro input(name, value='', type='text') -%}
    <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{%- endmacro %}

Что можно назвать так:

{% import 'forms.html' as forms %}
<dl>
    <dt>Username</dt>
    <dd>{{ forms.input('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ forms.input('password', type='password') }}</dd>
</dl>

Предполагая, что файл с макросом forms.html. Вы также можете поместить макрос в тот же файл, чтобы вам не пришлось импортировать.

person Wolph    schedule 19.11.2010
comment
Но опять же, меня интересует очевидный конфликт между DRY и разделением логики. Похоже, это решение выбрасывает последнего в окно. Это нормально, если вы согласны с этим, но есть ли более мирный способ примирения? - person jMyles; 19.11.2010
comment
@Justin Myles Holmes: Я использую это решение, потому что не думаю, что есть простой способ сделать это с самим Django. Вы можете обойти это, используя оператор with вместе с оператором include. Но это просто беспорядок ... как только вы начинаете делать что-то помимо оператора extends, вы нарушаете всякую возможность повторного использования. Как, например, администратор Django, где вы не можете изменить способ визуализации, не определив настраиваемые теги шаблонов. - person Wolph; 20.11.2010