我遇到以下问题:用户正在我的网站上学习课程。课程由几个章节组成,每章包含几个步骤。如果用户已登录并完成步骤,则后端将保存进度。当用户回到网站时,我希望他继续他离开的地方。为此,我必须将css类“active”添加到相应的导航步骤和每章的内容选项卡。我的出发点是如果用户已完成该步骤,则使用if语句进行测试。这很有效,但是对所有尚未完成的步骤添加.active。我只想将它添加到尚未完成的第一步。我实际上已经解决了这个问题,但它是一个相当粗暴的黑客,我不得不包括custom template tag that allows me to set a variable in the template:
{% 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 %}
我知道这也可以通过将列表或字典传递给包含所有活动步骤的模板,然后在模板中测试步骤是否在该列表中来完成。但这意味着重写了很多视图代码,所以我决定在模板中完成它。
所以我的问题是:解决这个问题的最佳做法是什么?我只是出于好奇而问,因为这个问题实际上很有趣。非常感谢!
答案 0 :(得分:2)
向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 %}
答案 1 :(得分:0)
我知道你已经解决了你的问题,我为了完成而发布了另一个答案。
如果您需要在{% 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 %}