шаблон django, измененный в шаблоне plist - PullRequest
1 голос
/ 24 декабря 2011

Я использую 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 change%} оценивалась на основе последней оценки, выполненной не в том же цикле. Но, конечно, это не фактическое поведение, потому что он, естественно, проверяет свои значения на основе последней итерации цикла. Как мне получить желаемый результат? Кроме того, массив тестов генерируется с помощью:

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

1 Ответ

1 голос
/ 24 декабря 2011

{% ifchanged%} должен работать, если набор "tests" упорядочен по testID.

Вы пробовали:

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

Вы также можете взглянуть на {% regroup%} tag.

[обновлено]

Как насчет пары тестов для 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>
...