1. Рома

    27.01.2010

    0 ↑
    3 ↓
    Добрый день!

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

    Например, в проекте есть приложения Блог и Новости.

    На главной странице, например, нужно вывести блок "Важные новости" с картинкой, вывести блок "обычные новости" в виде ссылок без картинок, вывести блок "интересные записи в блогах", "последние записи в блогах".

    Собственно вопрос, как будет правильнее все это организовать? Написать какой нибудь view_index() и в нем из вьюсов приложений Новости, Блог вызвать нужные функции и передать это все в шаблон? Но что то мне подсказывает, что правильным это решение назвать сложно :)

    Спасибо!
  2. Jury Koryakov

    27.01.2010

    1 ↑
    2 ↓
    Сначала стоит почитать маны по наследованию шаблонов
    http://docs.djangoproject.com/en/1.1/topics/templates/#topics-templates

    Затем подумать как лучше организовать свои шаблоны, чтобы они удовлетворяли вашим потребностям. Сразу это сделать вряд ли получится, но опытным путём поймёте как всё должно выглядеть. Один из основных критериев - повторяемость кода: как только чувствуете что код начал повторяться это и есть та точка где стоит остановится и подумать. Это работает не всегда, потому как готовых решений здесь нет, всё индивидуально. Глубина наследования не должна быть слишком высокой, лишь достаточной для комфортной раздельной работы с модулями ( где-то 2-3 ).

    Для вывода моделек пригодится вот этот ман
    http://docs.djangoproject.com/en/dev/ref/templates/builtins/

    Дальше, если хотите чтобы всё было совсем красиво, можно взглянуть на
    http://docs.djangoproject.com/en/1.1/howto/custom-template-tags/#howto-custom-template-tags
    и написать свои теги для вывода информации в шаблонах.
  3. demalexx

    28.01.2010

    0 ↑
    0 ↓

    Я для вывода одной и той же информации на разных страницах написал свой template tag. В шаблоне где надо получить данные, пишу такое:

    {% load blog_info %}
    ...
    {% blog_labels as sb_labels %}
    {% blog_posts as sb_posts %}
    

    И получаю в переменных sb_labels и sb_posts список ярлыков и лейблов. Не знаю, насколько хорошо решение :)

  4. Рома

    28.01.2010

    0 ↑
    0 ↓
    Спасибо за ответ,
    Наверно я не очень понятно задал вопрос, попробую исправиться :)

    Есть шаблоны base.html - базовый, и шаблоны hot_news.html, last_blogs.html - которые являются блоками и наследуют шаблон base.html.

    допусим eсть функции, которые выводят данные в эти шаблоны блоков
    def view_hot_news() 
    .....
    render_to_response(hot_news.html,.....)


    view_last_blogs()
    .....
    render_to_response (last_blogs.html,....)
    так же есть функция, которая "запускается" при обращении к корню сайта, то есть к главной странице - view_index()


    Мой глупый вопрос состоял в том, нужно ли во view_index() обращаться ко всем функциям типа view_hot_news() view_last_blogs(), которые "формируют" блоки главной страницы?


    demalexx, спасибо ) Может кто-нибудь нам подскажет, это стандартное решение, с темплейттагами?
  5. astur.net.ru

    28.01.2010

    0 ↑
    0 ↓

    Я бы, вместо того, чтобы переполнять вьюхи логикой, сделал бы функции для формирования контекстов блога и новостей соответственно. Во вьюхах блоговой и ньюсной страниц я бы их вызывал по одной, а во вьюхе главной страницы - обе. Для обоих контекстов я бы сделал по подключаемому шаблону. Шаблон блоговой страницы я бы наследовал от base.html, дополнительно инклюдя в него подключаемый шаблон блога. С шаблоном новостной страницы - также. В шаблоне главной страницы инклюдил бы оба подключаемых шаблона. Может я ошибаюсь, но мне этот способ кажется единственно-разумным.

    Если непонятно, могу дать пример кода (хоть и удивлюсь).

  6. Рома

    28.01.2010

    0 ↑
    0 ↓
    astur.net.ru, спасибо. Придется вас удивить - выложите пожалуйста пример кода :)
  7. Можно использовать декораторы.
    Схема следующая:
    1. Вьюха возвращает dict
    2. Новостной декоратор добавляет в него свой контект
    3. Декоратор блогов - свой и т.д.
    @render_to('my_template.html')
    @add_news_content
    @add_blog_content
    def my_view(...):
    return {'foo': 'bar'}
    ..
    Последний декоратор рендерит контекст и отдает HttpResponse.

    Если не хочется использовать декораторы, можно написать утилитки
    по дополнению контекста и дергать их в разных вьюхах:
    def my_view(...):
    ...
    context = {}
    context.update(add_news_content(request, ..))
    context.update(add_blog_content(request, ..))
    ...
    Ну и еще один вариант - использование своих тэгов (самый очевидный вариант),
    т.к. сохраняет изолированность приложений
  8. Рома

    28.01.2010

    0 ↑
    0 ↓
    Александр Добрецов, спасибо.
  9. demalexx

    28.01.2010

    0 ↑
    0 ↓

    Да, забыл, ещё в другом месте я делал почти как Александр Добрецов. Разница в том, что я написал свою функцию, которая: формирует словарик с site-wide значениями, добавляет его к переданному словарику, рендерит шаблон, используется во всех вьюхах.

    В таком случае нет возможности забыть в какой-то вьюхе вызвать функции, добавляющие значения, и получить ошибку в шаблоне :) Как-то так:

    def render(request, template, dict={}):
        dict['global_1'] = get_global_1(request);
        dict['global_2'] = get_global_2();
    
        return direct_to_template(request, template, dict)
    ...
    def get_global_1(request):
        ...
        return ...
    ...
    def get_global_2():
        ...
        return ...
    ...
    def view_index(request)
        ...
        render(request, 'template1', {'var1': 1, 'var2': 2})
    ...
    def view_page(request)
        ...
        render(request, 'template2')
    
  10. astur.net.ru

    28.01.2010

    2 ↑
    0 ↓

    Я удивился. Вот:

    view.py:

    from some_my_module import get_hot_news, get_last_blogs
    # в этих функциях надо реализовать то, вместо чего в вашем примере троеточия.
    
    @render_to('hot_news.html')
    def view_hot_news()
        return {'hot_news': get_hot_news()}
    
    @render_to('last_blogs.html')
    def view_last_blogs()
        return {'last_blogs': get_last_blogs()}
    
    @render_to('homepage.html')
    def view_homepage()
        return {'hot_news': get_hot_news(),
                'last_blogs': get_last_blogs()}
    

    last_blog.html:

    {%extends base.html%}
    {% block page %}
        {% include "last_blog_block.html" %}
        {% comment %}
            подключили ваш блок отображения блоговых записей
        {% endcomment %}
    {% endblock %}
    

    hot_news.html:

    {%extends base.html%}
    {% block page %}
        {% include "hot_news_block.html" %}
        {% comment %}
            подключили ваш блок отображения горячих новостей
        {% endcomment %}
    {% endblock %}
    

    homepage.html:

    {%extends base.html%}
    {% block page %}
        {% include "hot_news_block.html" %}
        {% include "last_blog_block.html" %}
        {% comment %}
            подключили оба блока
        {% endcomment %}
    {% endblock %}
    

    Вам это всё ещё не кажется элементарным?

  11. admin

    28.01.2010

    2 ↑
    0 ↓
    Использую http://github.com/marcinn/django-widgets . Виджеты позволяют дробить логику обработки запроса и формировать страницы из отдельных блоков.

    views.py:
    def get_portal_page(request):
    return render_to_response('portal_page.html')
    templates/portal_page.html:
    {% load widgets %}
    <html>
    ...
    <div class="column-left">
    {% include_widget LastNewsWidget max_rows=5 %}
    </div>
    <div class="column-right">
    {% include_widget LastBlogsWidget %}
    </div>
    ...
    </html>
    widgets.py:
    from django_widgets import Widget
    from models import News

    class LastNewsWidget(Widget):
    template = 'last_news_widget.html'

    def get_context(self, root_category, options):
    max_rows = options.get('max_rows', 5)
    return {
    'news': News.objects.get_last_news()[:max_rows],
    }

    }}}
  12. Рома

    28.01.2010

    0 ↑
    0 ↓
    demalexx, astur.net.ru, admin - спасибо большое!
  13. Никита Шультайс

    29.01.2010

    0 ↑
    0 ↓
    У меня есть приложение homepage, в него импортируются необходимые модели, делаются нужные выборки и всё передается в шаблон.
  14. Рома

    31.01.2010

    1 ↑
    0 ↓
    посмотрел различные варианты - для многих задач удобно использовать inclusion tags

    http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.