Общие шаблоны или шаблоны в моделях - Django - PullRequest
1 голос
/ 13 октября 2011

Каков наилучший подход в следующей ситуации?

Скажем, у нас есть некоторые модели, например, Article, Photo, BlogEntry и так далее. Каждая модель может быть отображена на странице в виде большого пальца или так называемого виджета.

Пример:

  • атрибут thumbview модели содержит большой палец элемента с заголовком в HTML-блоке
  • normalview - содержит большой палец, заголовок и описание в блоке
  • bigview - большой палец, название, описание и произнесение ... количество добавленных комментариев

Все это должно быть в некотором роде полиморфным в шаблоне, чтобы я мог сделать что-то вроде перебора моего списка абстрактных элементов (различных типов) и просто:

{{ item.thumbview }}

или

{{ item.bigview }}

для отображения каждого элемента большого пальца.

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

Как я могу смоделировать такое поведение? Какой самый лучший способ?

Буду признателен за любое предложение. Спасибо.

Ответы [ 2 ]

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

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

myapp/models.py:

class Photo(models.Model):
    ...
    def widget_context(self, context):  # receives the context of the template.
        user = context['request'].user  # context should be RequestContext to contain request object (or you may use thread locals).
        return {'tags': self.tag_set.filter(...), 'can_edit': self.owner == user or user.is_admin}

файл тегов шаблона, widgets_app/templatetags/objwidgets.py:

@register.simple_tag(takes_context=True)
def object_widget(context, obj, size='small'):
    context_func = getattr(obj, 'widget_context')  # try getting the context method
    extra_context = context_func(context) if context_func else {}
    extra_context['obj'] = obj

    long_tuple = (obj._meta.app_label, 'widgets', obj.__class__.__name__, size)
    return render_to_string([  # multiple templates to have both generic and specific templates
        '%s/%s/%s.%s.html' % long_tuple, # the most specific (photos/widgets/photo.small.html)
        '%s/widget.%s.%s.html' % (obj._meta.app_label, obj.__class__.__name__, size),
        '%s/widget.%s.html' % (obj._meta.app_label, size), # myapp/widget.small.html
        'widget.%s.html' % size,
    ],
    extra_context
    context)

использование:

{% load objwidgets %}
{% object_widget photo1 'large' %}
{% object_widget photo2 %}

создание шаблона для виджета объекта, myapp/widgets/photo.small.html:

<b>{{ obj.name }}</b>
<img src="{{ obj.thumbnail.url }}"/>
{% if can_edit %}<a href="{{ obj.get_edit_url }}">edit</a>{% endif %}
{% for t in tags %}
    <a href="{{ tag.get_absolute_url }}">{{ tag.text }}</a>
{% endif %}
0 голосов
/ 13 октября 2011

Вы не должны генерировать html вообще в вашей модели.Вы можете написать несколько пользовательских тегов шаблона , чтобы добиться того, что вам нужно.Если вы используете версию django dev, вы можете создать тег включения с аргументом, который может вернуть фрагмент html в зависимости от типа модели ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...