Абстрактное приложение Django из проекта

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

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

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

Предположим, я создаю веб-сайт. У моего веб-сайта есть внешний вид, и я определил 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 theincludeinurls.py` соответствующего корневого проекта. Все хорошо и хорошо, но как мне также прикрепить шаблон из этого проекта, то есть внешний вид? Я мог бы сделать все возможное и разработать базовый шаблон для приложения блога, но как насчет навигации и т. д.? Я мог бы захотеть включить один и тот же заголовок на каждой странице, даже если содержимое довольно разнообразно.

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

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

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

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


person Community    schedule 05.09.2010    source источник


Ответы (3)


Если я правильно понял вашу проблему, то я бы предложил сделать Пользовательский шаблон Тег. В нем вы можете делать все, что хотите: использовать 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')

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

person Peter Rowell    schedule 05.09.2010
comment
Привет, Питер, это похоже на то, что я ищу после моды - мне нужно немного изменить стратегию, потому что я хотел изолировать приложение блога от всего остального, но это невозможно, кажется. - person ; 05.09.2010
comment
Вряд ли когда-либо возможно полностью изолировать его, потому что что-то должно ссылаться на ваше приложение где-то. Я склонен помещать все специфичные для приложения вещи во включаемый файл, и это сводит к минимуму встроенные знания в других файлах. Единственное, что вы можете сделать (но это определенно квалифицируется как взлом), — это обработать вставку вашего приложения в промежуточное ПО. Я сделал это для наложения редактирования этого объекта на код администратора, но это был особый случай. Промежуточное программное обеспечение полезно, но при слишком умном использовании оно может свести с ума будущего специалиста по сопровождению, потому что это скрытая технология «человек посередине». - person Peter Rowell; 07.09.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 пытается выполнить концепцию неповторения, поэтому старайтесь избегать повторения блоков с наследованием/включением, это даст вам проект, который намного приятнее поддерживать!

person Bernhard Vallant    schedule 05.09.2010
comment
Привет lazerscience, да, я уже довольно часто использую расширения и блоки - чего я пытаюсь добиться, так это полной изоляции функциональности, поэтому я могу просто включить блог через settings.py, и он будет работать по адресу /blog, НО это будет также наследует внешний вид по умолчанию откуда-то, т.е. базовый шаблон html. Я не могу распространяться на проекты, я не думаю, или, говоря по-другому, если я расширяю базу в приложении блога и не предоставляю base.html для этого приложения и полагаюсь на то, что он предоставляется в другом месте, это работает? Я не думаю, что это будет. - person ; 05.09.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>

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

person Clueless    schedule 05.09.2010