Im ищет элегантное решение для моего дизайна шаблона в django. Я стараюсь сделать минималистский пример:Django - Templatetags, include и класс hierachy
На странице представлены разные функциональные области, например поле новостей и опрос, представленный собственными приложениями в django. Число этих областей совершенно иное, поэтому могут быть, например, три опроса и два поля новостей в определенном порядке (не отсортированы по типу).
Так вот пример реализации, как я бы решить эту проблему:
# in main app:
class Field(models.Model):
...
# in polls app:
class Poll(main.models.Field):
...
И для различного рода опросов:
class PrivatePoll(Poll):
...
Система шаблонов может затем перебирать объекты типа Field.
{% for field in fields %}
{% show_field field %}
{% endfor %}
Но моя проблема в том, что каждый подкласс поля или подкласса Poll нужен свой собственный способ отображения содержимого. Я знаю о templatetagвключение функция в Django, но templatetag затем должен различать подклассы и как их отображать ... Я хотел бы увидеть «код шаблона» каждого приложения внутри самого приложения, но я не получаю хорошее решение.
Что можно сказать о включают тег начиная с Django 1.7, который может представлять собой способ с визуализации()? Итак, что все классы и подклассы имеют метод render()? Я не понимаю, как использовать эту новую функциональность.
Любые идеи, как я могу это решить? Модели не должны быть подклассами, может быть, лучше иметь OneToOneRelationship s или что-то еще?
редактировать:
Могу ли я использовать включают тег, как это? Это хороший стиль джанго?
{% for field in fields %}
{% include field.render %}
{% endfor %}
edit2:
я написал свой собственный шаблонный тег, как вышеписанной документации. Но это правильный способ сделать это?
from django import template
from django.template.loader import render_to_string
register = template.Library()
@register.tag
def display_object(parser, token):
try:
tag_name, tile_object, template_to_render = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError("%r tag requires exactly two arguments" % token.contents.split()[0])
return MyNode(tile_object, template_to_render)
class MyNode(template.Node):
def __init__(self, tile_object, template_to_render):
self.tile_object = template.Variable(tile_object)
self.template_to_render = template_to_render
def render(self, context):
try:
tile_object = self.tile_object.resolve(context)
return render_to_string(self.template_to_render, tile_object)
except template.VariableDoesNotExist:
return ''
Теперь теоретически я могу использовать его в моем шаблоне:
{% for field in fields %}
{% display_object field field.template_to_use %}
{% endfor %}
Но он чувствует себя не правильно, особенно display_object(..)
, где переменные передаются строками ..!? И не сталкивается с этой строкой, если я вызываю display_object
с field
несколько раз, потому что это всегда одна и та же строка «поле», которая передается ..!?
Все, что я хочу, это отображать шаблоны, указанные в экземпляре объекта, является ли такой трудный способ единственным способом решить эту проблему? Или я должен перестроить свою иерархию по-другому?
Edit3:
Хорошо после того, как много больше исследований, это именно то, что делает include
тег (source code). Я не понимаю, почему так много людей (в форумах/на StackOverflow) говорят, что «включить» не следует использовать ...
Итак, наконец, это будет мое решение:
{% for field in fields %}
{% include field.template_to_render with context=field.context %}
{% endfor %}
Любые предложения?
Но «включить поле» я не должен использовать из-за нарушения, которое вы описали? – FaBay
Хорошо, перепишите 'show_field', но как изменить шаблон для 'include_tag'? Я мог бы вернуть здесь «render_to_string»: [link] (http://stackoverflow.com/questions/17178525/django-how-to-include-a-view-from-within-a-template), но это кажется, не является правильной реализацией. В документации построен «узел» для пользовательских тегов шаблонов ... – FaBay
Динамическое изменение шаблона для 'включения_tag' вы не можете, вам нужно написать весь template_tag (парсер и узел). Но не волнуйтесь, это хорошо документировано (https://docs.djangoproject.com/en/1.7/howto/custom-template-tags/#writing-custom-template-tags) и проще, чем сначала. –