我在django中为我的模板设计寻找一个优雅的解决方案。我试着做一个极简的例子:
页面上有不同的功能区域,例如一个新闻字段和一个由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的子类都需要自己的方式来显示内容。我知道Django中的templatetag包含函数,但是templatetag必须区分子类和如何呈现它。我想看到每个应用程序的“模板代码”在应用程序本身,但我没有一个好的解决方案。
如何处理Django 1.7之后的include标记,它可以用render()表示方法?这样所有的类和子类都有一个呈现()方法?我不知道如何使用这个新功能。
我有什么办法解决这个问题吗?模型不必是子类,也许拥有_OneToOneRelationship_s或其他什么更好?
编辑:
我可以像这样使用包含标签吗?这是一种好的django风格吗?
{% 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标签所做的(源代码)。我不明白为什么这么多的人(在论坛/堆叠溢出)说‘包括’不应该使用.
最后,这将是我的解决方案:
{% for field in fields %}
{% include field.template_to_render with context=field.context %}
{% endfor %}有什么建议吗?
发布于 2014-12-05 16:25:30
如何处理Django 1.7之后的include标记,它可以用render()表示方法?这样所有的类和子类都有一个呈现()方法?
从理论POV来看,这将违反层的响应性,因为模型是用于域逻辑的,而不是表示的。当然,除非模型的“域逻辑”仅仅(或者大部分)是关于表示的(比如cms页面之类的)
但我的问题是,每个字段的子类或Poll的子类都需要自己的方式来显示内容。
这意味着每个子类都有一个模板。最简单的解决方案是将模板路径指定为模型的类属性,然后重写show_field模板以使用该模板来呈现.
我可以像这样使用包含标签吗?这是一种好的django风格吗? {%字段中的% %} {%包括field.render %} {% for %}
假设field.render是以上下文为参数的方法,那么(技术上)正确的用法是:
{% for field in fields %}
{% include field %}
{% endfor %}https://stackoverflow.com/questions/27319589
复制相似问题