Regelmäßige Besucher der Website, die die Suche auf der Website verwenden, haben wahrscheinlich bemerkt, dass sich die Anzeige von Artikeln von der Anzeige von Kommentaren in den Suchergebnissen der Website unterscheidet. Dies wurde dadurch erreicht, dass jeder Inhaltstyp seine eigene Rendering-Vorlage hat, die ersetzt wird, wenn die Seite gerendert wird, je nachdem, welche Inhalte bei der Suche gefunden wurden.
Schauen wir uns ein Ausgabebeispiel an.
Sie sehen, hier unterscheidet sich die Kommentardarstellung vom Artikel, aber sie werden in den gleichen Suchergebnissen angezeigt, wie dies im vorherigen Artikel der Fall war.
Aber es ist viel eleganter als die Auswahl über if else . Ehrlich gesagt gefällt mir diese Lösung sehr gut.
Für jedes Datenmodell muss ein Feld definiert werden, das den Pfad zur Vorlage zur Anzeige des Objekts dieses Modells speichert. In diesem Fall muss dieses Feld in jedem Modell denselben Namen haben. Es ist sehr wichtig.
Lassen Sie uns zum Beispiel dies tun
class Article(models.Model): TEMPLATE_PREVIEW = 'home/article_preview.html' class Comment(models.Model): TEMPLATE_PREVIEW = 'home/comment_preview.html' class Topic(models.Model): TEMPLATE_PREVIEW = 'home/topict_preview.html' class Post(models.Model): TEMPLATE_PREVIEW = 'home/post_preview.html'
In jeder dieser Vorlagen können wir eine eigene Inhaltsanzeige vorschreiben, die nicht erforderlich ist. Zum Beispiel für einen Artikel
<div> <a href="{{ object.get_absolute_url }}"><h2>{{ object.itle }}</h2></a> {{ object.content|safe }} <p><a class="btn btn-default btn-sm" href="{{ object.get_absolute_url }}">Читать далее</a></p> </div>
Und für alle anderen Vorlagen können wir etwas anderes schreiben. Die Hauptsache ist, dass alle Methoden und Felder sowie der Name eines einzelnen Objekts in allen Vorlagen gleich sind.
Und die Suchergebnisvorlage selbst könnte so aussehen
{% load tz %} {% load trans from i18n %} {% load bootstrap_pagination from bootstrap4 %} <div id="object-list"> {% for object in object_list %} {% include object.TEMPLATE_PREVIEW %} {% empty %} <div class="card card-body mb-3">{% trans 'Ничего не найдено' %}</div> {% endfor %} {% bootstrap_pagination object_list pages_to_show="10" url=last_question %} </div>
Die Nuance ist, dass wir daran gewöhnt sind, einen String-Template-Namen an das include -Tag zu übergeben, so wie hier
{% include 'home/article_preview.html' %}
Aber niemand hat gesagt, dass dies der einzige Weg ist, und auch niemand hat gesagt, dass wir den Pfad zum Template nicht direkt von dem Objekt nehmen können, dessen Inhalt wir rendern möchten. Das heißt, Sie können leicht schreiben
{% include object.TEMPLATE_PREVIEW %}
Und wenn wir berücksichtigen, dass jedes Objekt seine eigene TEMPLATE_PREVIEW hat, dann werden die Dateien dort anders verbunden, was bedeutet, dass jede Art von Inhalt ihren eigenen Rendering-Stil hat.
Für Django empfehle ich VDS-Hosting TIMEWEB
интересное решение! интересно как реализовать такое через
Django REST
К сожалению, я сейчас мало использую django_rest_framework , но в будущем планирую значительную часть работы сайта переводить на него. Поэтому придумаю какое-нибудь подобное решение с использованием какого-нибудь JS-шаблонизатора.
Идея с классовыми параметрами интересна, однако при большом количестве элементов, это может занять значительные время. И дело даже не в решении, а в тэге include. При его использовании, шаблон будет искаться для каждого использования без учёта того, что это один и тот же шаблон. Если выводится 50, 100 или сколько-нибудь адекватное количество элементов - можно жить, но надо помнить, что в этом месте можно неслабо так порезаться.
Согласен с вами!
через классовый метод не обойтись
мне кажется лучше это сделать на стороне клиента где при помощи vue js! а в модель сделать свойство по которому js будет генерирывать шаблон
А я вот планирую внедрять nunjucks, он очень сильно похож по синтаксису на шаблоны Django, и также поддерживает наследование шаблонов. Пробный запуск я уже делал и весьма понравилось. Но пока не внедрял в качестве боевого варианта, есть ещё где развернуться по оптимизациям на стороне сервера.
либо не греть голову и сделать несколько тэгов - для каждой модели. а в классе модели определить какую-то переменную (например однобуквенную:) ) по которой бы определялось, какой тэг использовать. а если этот механизм часто используется, код выбора нужного тэга сунуть в еще один шаблон и сделать inclusion_tag. получится длинная цепочка, и, возможно, немного запутанная, но получится достаточно быстро
запутанная... уже что-то пугает ....
Мысль о inclusion_tag мне весьма импонирует. Как вариант, можно хранить также путь к шаблону в параметре класса, а в данном теге уже искать шаблоны и делать кеширование, чтобы не скать каждый раз.
Вообще, я полностью согласен. Подобное лучше всего отдать на откуп клиенту.
Запутанность - условная. Будет просто цепочка вызовов inclusion_tag-ов. Причём первое звено нужно лишь для возможности повторного использования. Если таковое не предполагается, можно опустить один уровень.
Думаю, что это всё равно стоит оставить для индексирующих роботов поисковых систем, которые испоьлзуют простые GET запросы. Они же AJAX не используют. Так что полностью уйти от этого не получится, если есть открытый контент на сайте.