首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django -Templatetag,包括等级和等级

Django -Templatetag,包括等级和等级
EN

Stack Overflow用户
提问于 2014-12-05 15:45:07
回答 1查看 371关注 0票数 1

我在django中为我的模板设计寻找一个优雅的解决方案。我试着做一个极简的例子:

页面上有不同的功能区域,例如一个新闻字段和一个由django中自己的应用程序所代表的民意测验。这些区域的数量是非常不同的,因此可以有三个投票和两个新闻字段,按一个特定的顺序(而不是按类型排序)。

下面是一个示例实现,我将如何解决这个问题:

代码语言:javascript
复制
# in main app:
class Field(models.Model):
...

# in polls app:
class Poll(main.models.Field):
...

对于不同类型的民意调查:

代码语言:javascript
复制
class PrivatePoll(Poll):
...

然后,模板系统可以迭代类型为Field的对象。

代码语言:javascript
复制
{% for field in fields %}
    {% show_field field %}
{% endfor %}

但我的问题是,每个字段的子类或Poll的子类都需要自己的方式来显示内容。我知道Django中的templatetag包含函数,但是templatetag必须区分子类和如何呈现它。我想看到每个应用程序的“模板代码”在应用程序本身,但我没有一个好的解决方案。

如何处理Django 1.7之后的include标记,它可以用render()表示方法?这样所有的类和子类都有一个呈现()方法?我不知道如何使用这个新功能。

我有什么办法解决这个问题吗?模型不必是子类,也许拥有_OneToOneRelationship_s或其他什么更好?

编辑:

我可以像这样使用包含标签吗?这是一种好的django风格吗?

代码语言:javascript
复制
{% for field in fields %}
    {% include field.render %}
{% endfor %}

edit2:

我编写了自己的模板标记,就像文档中描述的那样。但这是正确的方法吗?

代码语言:javascript
复制
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 ''

现在,理论上我可以在我的模板中使用它:

代码语言:javascript
复制
{% for field in fields %}
    {% display_object field field.template_to_use %}
{% endfor %}

但这感觉不正确,特别是display_object(..),其中的变量是通过字符串传递的.!?如果我多次使用display_object调用field,不会与此字符串发生冲突,因为它始终是传递的相同的字符串“字段”。

我想要的只是呈现从对象实例中指定的模板,这是解决这个问题的唯一方法吗?还是我应该以另一种方式重建我的等级制度?

edit3:

好吧,经过更多的研究,这正是include标签所做的(源代码)。我不明白为什么这么多的人(在论坛/堆叠溢出)说‘包括’不应该使用.

最后,这将是我的解决方案:

代码语言:javascript
复制
{% for field in fields %}
    {% include field.template_to_render with context=field.context %}
{% endfor %}

有什么建议吗?

EN

回答 1

Stack Overflow用户

发布于 2014-12-05 16:25:30

如何处理Django 1.7之后的include标记,它可以用render()表示方法?这样所有的类和子类都有一个呈现()方法?

从理论POV来看,这将违反层的响应性,因为模型是用于域逻辑的,而不是表示的。当然,除非模型的“域逻辑”仅仅(或者大部分)是关于表示的(比如cms页面之类的)

但我的问题是,每个字段的子类或Poll的子类都需要自己的方式来显示内容。

这意味着每个子类都有一个模板。最简单的解决方案是将模板路径指定为模型的类属性,然后重写show_field模板以使用该模板来呈现.

我可以像这样使用包含标签吗?这是一种好的django风格吗? {%字段中的% %} {%包括field.render %} {% for %}

假设field.render是以上下文为参数的方法,那么(技术上)正确的用法是:

代码语言:javascript
复制
{% for field in fields %}
   {% include field %} 
{% endfor %}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27319589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档