Абстрактное приложение Django от «Проекта» - PullRequest
0 голосов
/ 05 сентября 2010

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

По сути, мой вопрос состоит в том, как правильно абстрагировать функциональность приложения, если указанная функциональность обнаружена в приложении, являющемся частью проекта?

Чтобы добавить некоторый контекст этому (этоне далеко от того, чего я пытаюсь достичь):

Предположим, я создаю веб-сайт.Мой веб-сайт выглядит и работает, и я определил base.html шаблон и различные css-элементы в приложении django без модели.

Теперь я также пишу приложение для блога django.Я знаю, как включить его так, чтобы модели появлялись в моем текущем приложении, и я более чем счастлив, что могу использовать любой метод, который мне нравится, из различных пакетов, манипулировать моделями и выполнять с ним все Python.

Чего я не понимаю, так это как обращаться с мнениями.Кажется нелогичным, что модели хранятся где-то в другом месте, но им приходится создавать пользовательский интерфейс в моем текущем проекте (и, как следствие, в любом последующем проекте).Итак, я подумал, хорошо, добавьте urls из папки моего приложения в мой проект, готово.

Тогда, конечно, мне нужно написать представления, и это нормально.Я могу это сделать.

Что я не могу понять, так это то, как вписываются шаблоны: в моем приложении я хочу использовать такой шаблон:

<div class="entry">
<a href=""><h2>{{ entry.Title }}</h2></a>
<p>Published on: {{ entry.date_published|date:"j F Y" }}</p>
{{ entry.body_html }}
</div>
<a href="">X comments.</a>&nbsp;<a href=""">Add Comment</a>&nbsp;<a href="">Link</a>

<div id="commentdiv">
{% if comments %}
    <ul id="commentlist">
    {% for comment in Comments %}
        <li></li>
    {% endfor %}
    </ul>
{% else %}
    <p>There are no comments on this entry.</p>
{% endif %}

</div>

для просмотразапись, поэтому на моем сайте я захожу на sitename.com/blog/...someparameters.../entryname' where blog is the include in urls.py` соответствующего корневого проекта.Все хорошо, но как мне также прикрепить шаблон из этого проекта, то есть внешний вид?Я мог бы изо всех сил и разработать базовый шаблон для приложения блога, достаточно справедливо, но как насчет навигации и т. Д.?Я мог бы захотеть включить один и тот же заголовок на каждую страницу, даже если содержимое довольно разнообразно.

Теперь я знаю о директиве {% extends "template"%} и директиве {% include template%},Почему они не работают, насколько я понимаю:

  • {% extends%} - как мне узнать / предоставить то, что я хочу расширить из корневого проекта?Если вы можете предоставить механизм для этого, я думаю, что это решит проблему очень хорошо.
  • {% include%} - подразумевает, что я должен предоставить представления для блога в загрузочном приложении в корневом проекте.Я действительно не хочу этого делать - я могу с таким же успехом перенести весь проект в этом случае.

Итак, мой вопрос: как мне все это собрать вместе?

Редактировать : Я думаю этот вопрос очень похож на то, что я спрашиваю, и отметил ответы.Тем не менее, они все еще не удовлетворяют.

Ответы [ 3 ]

1 голос
/ 05 сентября 2010

Если я правильно понимаю вашу проблему, то я бы предложил сделать Пользовательский тег шаблона .В нем вы можете делать все, что захотите: использовать 0 или более аргументов для тега, чтобы получить и манипулировать произвольными объектами, а затем вызвать механизм шаблонов «вручную», чтобы получить фрагмент кода для возврата.Например,

[...]
t = loader.get_template('sometemplate.html')
c = Context({
    'my_data': my_data, # or whatever
})
return t.render(c) # this gets inserted into the invoking template

Если вы не хотите, чтобы различные "основные шаблоны" сайта выполняли {% load ...%}, вы можете вставить что-то вроде следующего в __init__.pyкаталога приложения:

from django import template
template.add_to_builtins('myapp.templatetags.myapptags')

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

0 голосов
/ 05 сентября 2010

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

Например:

base.html (в шаблонах вашего проекта):

<html>
  <head>
    <title>{% block "title" %}Default title{% endblock %}</title>
  </head>
  <body>
    <div id="nav">{% block "nav" %}{% endblock %}</div>
    <div id="content">{% block "content" %}{% endblock %}</div>
  </body>
</html>

template_name.html (в шаблонах приложения):

{% extends "base.html" %}

{% load other_app_tags %}

{% block "nav" %}
  {% other_app_nav_tag %}
{% endblock %}

{% block "content" %}
  lotsa good junk.
{% endblock %}

other_app_tags.py(в каталоге templatetags другого приложения):

from django import template

register = template.Library()

@register.inclusion_tag('navigation.html')
def other_app_nav_tag():
    # You could give this tag arguments to change how it behaves
    return {
        'links': {
            'Home': '/home'
        }
    }

navigation.html (в шаблонах другого приложения):

<ul>
{% for text, target in links %}
  <li><a href="{{ target }}">{{ text }}</a></li>
{% endfor %}
</ul>

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

0 голосов
/ 05 сентября 2010

Если вы хотите использовать шаблонное наследование с django таким способом, который имеет смысл, вам нужно использовать не только тег {% extends %}, но и тег {% block %}!Укажите в своем базовом шаблоне блоки, которые должно заменить ваше приложение: Например:

<html>
    <body>
         <div id="content">
         {% block "content" %}
         {% endblock %}
         </div>
    </body>
</html>

Затем вы можете легко заполнить содержимое div своим приложением с наследованием шаблона:

{% extends "base.html" %}
{% block "content" %}
    The content generated by your app.
{% endblock %}

Вы должны помнить, что язык шаблонов Django также пытается реализовать концепцию неповторения, поэтому старайтесь избегать повторения блоков с наследованием / включением, это даст вам проект, который гораздо приятнее поддерживать!

...