【问题标题】:django template ifchanged within plist templatedjango 模板 ifchanged 在 plist 模板中
【发布时间】:2012-01-27 01:39:36
【问题描述】:

我正在使用 Django 生成格式为 plist 的模板,以便在 iPhone 应用程序中直接使用。但是,我无法根据我的数据库正确输出 plist。本质上,我有一个包含测试的表。每个都有一个 testID 和一个 test_type。该表使用 unique_together 子句来确保没有两个条目具有相同的 testID 和 test_type,并且它还按 testID 和 test_type 对结果进行排序。但在我的模板中,我想在同一个字典中将所有具有相同 testID 的测试分组。 我的模板看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>all_tests</key>
    <array>
        {% for t in tests %}
        {% ifchanged t.testID %}<dict>
            <key>testID</key>
            <string>{{ t.testID }}</string>
            <key>sections</key>
            <array>{% endifchanged %}
                <dict>
                    <key>pk</key>
                    <integer>{{ t.pk }}</integer>
                    <key>type</key>
                    <string>{{ t.test_type }}</string>
                    <key>num_questions</key>
                    <integer>{{ t.num_questions }}</integer>
                </dict>
            {% ifchanged t.testID %}</array>
        </dict>{% endifchanged %}{% endfor %}
    </array>

本质上,我希望 {% if changed %} 指令根据上次评估的时间进行评估,而不是在同一个循环中。但这当然不是实际行为,因为它自然会根据最后一次循环迭代检查其值。我应该如何产生我想要的输出?此外,测试数组是通过以下方式生成的:

tests = Test.objects.annotate(num_questions=Count('questions')).filter(num_questions__gt=0).all()

【问题讨论】:

    标签: django templates django-templates plist


    【解决方案1】:

    如果“测试”集按 testID 排序,则 {% ifchanged %} 应该可以工作。

    你试过了吗:

    tests = Test.objects\
                   .annotate(num_questions=Count('questions'))\
                   .filter(num_questions__gt=0)\
                   .order_by('testID').all()
    

    你也可以看看{% regroup %}标签。

    [更新]

    forloop.{first,last} 的几个测试怎么样? (抱歉,未经测试...)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>all_tests</key>
        <array>
            {% for t in tests %}
            {% ifchanged t.testID %}
              {% if not forloop.first %}
                </array>
              </dict>
              {% endif %}
              <dict>
                <key>testID</key>
                <string>{{ t.testID }}</string>
                <key>sections</key>
                <array>{% endifchanged %}
                    <dict>
                        <key>pk</key>
                        <integer>{{ t.pk }}</integer>
                        <key>type</key>
                        <string>{{ t.test_type }}</string>
                        <key>num_questions</key>
                        <integer>{{ t.num_questions }}</integer>
                    </dict>
              {% if forloop.last %}
                </array>
              </dict>
              {% endif %}
        </array>
    

    【讨论】:

    • 我的结果已经由 testID 列自动排序,这只是在模型中声明,所以我不必在调用中明确声明排序
    • 问题与在第一个循环中触发第一个 ifchanged 的​​条件相同,也会触发最后一个 ifchanged。实际上,我希望最后一个 ifchanged 仅在具有 commen testID 的测试子集中的最后一个对象上触发。我需要在我的视图的方法中手动完成吗?
    猜你喜欢
    • 2018-10-21
    • 2019-12-22
    • 2022-01-12
    • 2015-09-07
    • 1970-01-01
    • 2011-09-07
    • 2015-10-25
    • 2013-06-13
    • 2018-11-25
    相关资源
    最近更新 更多