1

我有以下问题:用户正在我的网站上学习课程。一门课程由几个章节组成,每章包含几个步骤。如果用户已登录并完成一个步骤,则后端会保存进度。当用户回到站点时,我希望他从他离开的地方继续。为此,我必须将 css 类“活动”添加到相应的导航步骤和每章的内容选项卡中。我的出发点是使用 if 语句测试用户是否已经完成了该步骤。效果很好,但是将 .active 添加到所有尚未完成的步骤中。我只想将它添加到尚未完成的第一步。我实际上已经解决了这个问题,但这是一个相当粗暴的黑客攻击,我必须包括一个允许我在模板中设置变量的自定义模板标签

{% load custom_tags %}

{% for chapter in chapters %}
<div>
    <ul class="unstyled wizard clearfix">
        {% set active_wizard_steps = 0 %}
        {% for step in chapter.steps.all %}
        <li class="{% if not step.read and active_wizard_steps == 0 %}active{% set active_wizard_steps = 1 %}{% endif %}{% if step.read %} finished{% endif %}"></li>
        {% endfor %}
    </ul>
</div>
{% endfor %}

我知道这也可以通过将列表或字典传递给包含所有活动步骤的模板来完成,然后在模板中测试是否有步骤在该列表中。但这意味着要重写很多视图代码,所以我决定完全在模板中完成。

所以我的问题是:解决这个问题的最佳实践方法是什么?我只是出于好奇而问,因为这个问题实际上很有趣。非常感谢!

4

2 回答 2

3

向 Step 添加方法:

class Step(models.Model):
    # ...
    def is_active(self):
        # do your sauce

在模板中:

class="{% if step.is_active %}active{% endif %}"

我们在模型中已经有了像 get_absolute_url 这样方便的助手,为什么不添加这个呢?

如果你不喜欢它,你可以做一个模板过滤器并像这样使用它:

class="{% if step|is_active %}active{% endif %}"

更新

这是另一种方法,像这样制作模板过滤器:

@register.filter
def set_active_steps(steps):
    active_wizard_steps = 0

    for step in steps:
        if not step.read and active_wizard_steps == 0:
            step.is_active = True

    return steps

然后,在您的模板中:

{% for step in chapter.steps.all|set_active_steps %}
    ... {% if step.is_active %}...{% endif %}
{% endfor %}
于 2012-09-17T13:18:54.290 回答
0

我知道您已经解决了您的问题,为了完成,我发布了另一个答案。

如果您需要在 a{% for %}{% endfor %}中通过将当前向导步骤与循环中的当前项进行匹配来设置类,则可以使用以下代码:

{% for step in wizard.steps.all %}
    <li class="{% if wizard.steps.step1 == forloop.counter %}active{% elif wizard.steps.step1 > forloop.counter %} complete{% endif %}">
          <span class="step">{{ forloop.counter }}</span>
    </li>
 {% endfor %}
于 2014-12-08T13:47:02.210 回答