Проблема зацикливания со словарем в шаблонах Django - PullRequest
5 голосов
/ 21 июня 2011

Я не уверен, почему этот шаблон ничего не отображает на странице. Есть ли что-то очевидное, чего мне здесь не хватает?

Вид:

@user_passes_test(is_staff)
def details_activity_log(request, project_id, template='projects/details_activity_log.html'):

    project = get_object_or_404(Project.objects.select_related(), pk=project_id)
    action_log = project.projectactionlog_set.all()

    log_group = defaultdict(list)

    for log in action_log:
        log_group[log.action_time.strftime('%y%m%d')].append(log)


    #import pdb; pdb.set_trace()

    return render_to_response(template, {
        'log_group'  : log_group,
        'project'    : project,
        'action_log' : action_log,
        'tab_5'      : 'active',
    }, context_instance=RequestContext(request))

log_group содержит dict объектов модели, например:

defaultdict(<type 'list'>, {'110614': [<ProjectActionLog: ProjectActionLog object>, ...]}) 

Шаблон:

   {% for key, log in log_group %}
      {% for action in log %}
        {{ action }}
        {{ action.action_time }}                    
        {{ action.user.first_name }}
        {{ action.message }}
        {{ action.object_name }}
      {% endfor %}
    {% endfor %}

Редактировать Если бы я только посмотрел в документах, я бы увидел ответ. https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for

Однако это сложная ситуация, поскольку шаблоны не выдают никаких ошибок времени выполнения, когда цикл не может распаковать элементы итератора.

Ответы [ 3 ]

8 голосов
/ 21 июня 2011

Изменить

{% for key, log in log_group %}

на

{% for key, log in log_group.items %}
5 голосов
/ 21 июня 2011

Обновите ваш цикл for:

{% for log in log_group.itervalues %}

Или, если вам действительно нужно key (ваш пример шаблона не показывает его использование):

{% for key, log in log_group.iteritems %}
3 голосов
/ 23 января 2013

Также будьте очень осторожнее с defaultdicts в шаблоне django, и я вижу в вашем коде, что вы действительно используете defaultdict.

Они явно не работаюткак и ожидалось в шаблоне из-за того, как django пытается получить доступ к свойствам / атрибутам / и т. д.и единственное решение состоит в том, чтобы преобразовать их в dicts:

context['dictstructure'] = dict(mydefaultdict)

документация шаблона *1011* была исправлена ​​после ticket # 16335 , changeset ввключите специальное уведомление по этому вопросу.

Технически, когда система шаблонов встречает точку, она пытается выполнить следующие поиски в следующем порядке:

  • Поиск в словаре
  • Поиск атрибута
  • Вызов метода
  • Поиск по индексу списка

Это может вызвать неожиданное поведение с объектами, которые переопределяют поиск по словарю.Например, рассмотрим следующий фрагмент кода, который пытается циклически перебрать коллекцию collection.defaultdict:

{% for k, v in defaultdict.iteritems %}
    Do something with k and v here... 
{% endfor %} 

Поскольку поиск в словаре происходит первым, это поведение включается и предоставляет значение по умолчанию вместо использования предполагаемого .iteritems () метод.В этом случае сначала рассмотрите возможность преобразования в словарь.

Также см. Вопрос Шаблон Django не может зациклить defaultdict

...