在django模板中迭代两次列表

时间:2016-11-19 14:36:34

标签: python django django-templates

在我的django模板中,我正在创建两个标签 - “所有活动”和“您的活动”。在第一个选项卡中,我想列出所有事件,在第二个选项卡中,我想要一个过滤的事件列表(用户正在参加的事件)。

要做到这一点,我在同一个列表上循环两次。第一次迭代都很好,但第二次迭代没有给出任何输出。我该如何解决?

在下面发布我的html模板。

{% block content%}

<ul class="nav nav-tabs" style="padding-top: 60px">
  <li class="active"><a data-toggle="tab" href="#allevents">All events</a></li>
  <li class=""><a data-toggle="tab" href="#yourevents">Your events</a></li>
</ul>

<div class="container-fluid">
    <h1>Event list</h1>
</div>

<div class="tab-content">
    <div id="allevents" class="tab-pane fade in active">
    {% for event, is_att in event_zip %}

    <p> {{ event.name }} </p>
    DISPLAY ALL EVENTS HERE - displays correctly

    {% endfor %}
    </div>

    <div id="yourevents" class="tab-pane fade">
    {% for event, is_att in event_zip %}

    <!-- {% if is_att %} --> 
    <p> {{ event.name }} </p>
     DISPLAY FILTERED EVENTS HERE - doesn't give any output
     Does not work even with 'if' statement commented out.
    <!-- {% endif %} -->

    {% endfor %}
    </div>


</div>

{% endblock %}

views.py

@login_required
def events(request):
    user = request.user

    event_list = Event.objects.all().order_by('date')
    is_att = []

    for e in event_list:
        ev = get_object_or_404(Event, pk=e.id)
        if user in ev.list_of_users.all():
            is_att.append(True)
        else:
            is_att.append(False)

    event_zip = zip(event_list, is_att)

    if request.POST.get('join'):
        event_id = request.POST['join']
        event_to_join = get_object_or_404(Event, pk=event_id)
        event_to_join.list_of_users.add(user)
        return HttpResponseRedirect(reverse('events'))

    if request.POST.get('leave'):
        event_id = request.POST['leave']
        event_to_leave = get_object_or_404(Event, pk=event_id)
        event_to_leave.list_of_users.remove(user)
        return HttpResponseRedirect(reverse('events'))

    return render(request, 'events/events.html', {'event_zip' : event_zip})

活动模型

class Event(models.Model):
    name = models.CharField(max_length=50, blank=False, unique=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateTimeField(blank=False)
    place = models.CharField(max_length=50, blank=False)
    list_of_users = models.ManyToManyField(User, related_name='user_list', blank=True)

    @property
    def is_in_future(self):
        return self.date > timezone.now()

    def __str__(self):
        return self.name

2 个答案:

答案 0 :(得分:2)

你正在使用Python 3,其中zip是一个生成器;生成器只能迭代一次。

您可以通过明确调用list来解决此问题:

event_zip = list(zip(event_list, is_att))

但实际上这已经是一件非常低效的事情了。对于每个事件,您都在请求所有关联用户,然后测试当前用户是否在该列表中。相反,您应该只执行一个单独的查询来获取与用户关联的所有事件:

 user_events = Event.objects.filter(list_of_users=user)

并将该对象单独传递给模板。

(请注意,此查询也可以拼写为user_events = user.user_list.all() - 这会让您感到不必要的混乱,因为您在事件模型上使用了错误的related_name。名称应为event_list,因为它给出了您是与该用户相关的事件列表;或者,只需将该参数完全保留,这样您就可以获得默认值event_set。)

答案 1 :(得分:0)

你评论出来&#34; if is_att&#34;在第二个循环中。而不是:

<!-- {% if is_att %} --> 

你应该使用

{# if is_att #}

if语句仍在django模板中使用