2

In my django template I'm creating two tabs - 'All events' and 'Your events'. In the first tab I want to list all of the events and in the second tab I want to have a filtered list of events (events that user is attending).

To do this I'm looping twice over the same list. The first iteration is all good, but the second doesn't give any output. How can I fix it?

Posting my html template below.

{% 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}) 

Event model

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 
5
  • What is the value of is_att ? Commented Nov 19, 2016 at 14:41
  • Make isat a list instead of an iterator Commented Nov 19, 2016 at 14:43
  • Please show the view. What is event_zip? Commented Nov 19, 2016 at 14:51
  • is_att is a boolean list, True if user joined event, False if he did not Commented Nov 19, 2016 at 14:53
  • added view and model Commented Nov 19, 2016 at 14:59

2 Answers 2

3

You're using Python 3, where zip is a generator; generators can only be iterated once.

You could fix this by calling list explicitly:

event_zip = list(zip(event_list, is_att)) 

but really this is already a very inefficient thing to be doing. For every event, you're requesting all associated users and then testing whether the current user is in that list. Instead you should simply do a single separate query to get all the events that the user is associated with:

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

and pass that object separately to the template.

(Note this query could also be spelled user_events = user.user_list.all() - that is unnecessarily confusing because you have used a misnamed related_name on the Event model. The name should be event_list, because it gives you a list of events related to that user; or, just leave that parameter out altogether so you will get the default, event_set.)

Sign up to request clarification or add additional context in comments.

Comments

0

You comment out "if is_att" in the second loop wronly. Instead of:

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

You should use

{# if is_att #} 

The if statement is still used in the django template

1 Comment

Actually I don't have these lines in my code, just added it here to show I want to filter it. {% for event, is_att in event_zip %} doesn't give any output when called for the second time

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.