Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Grouping querysets by a certain field in template

Tags:

python

django

I have a table Events, ordered by a field date.

I want to print out the events in the template, but using a separate div for each date, e.g.:

<div class="content">
  <h1>December 30th</h1>
  <!-- div for Event 1 from December 30th -->
  <!-- div for Event 2 from December 30th -->
</div>

<div class="content">
  <h1>December 31st</h1>
  <!-- div for Event 1 from December 31st -->
  <!-- div for Event 2 from December 31st -->
  <!-- div for Event 3 from December 31st -->
</div>

How do I do this?


My current solution is to put the Event objects in a dictionary with the date as the key. This has ordering issues and is inelegant and inefficient.

View:

events = Event.objects.select_related().all()

events_dict={}
for event in events:
    date=event.date.strftime('%d %B %Y')
    if date in events_dict:
        events_dict[date].append(event) 
    else:
        events_dict[date] = [event]

Template:

{% for date, events in events_dict.items %}
  <div class="content">
    <h1>{{date}}</h1>
    {% for event in events %}
      {% include "partials/event.html" %}
    {% endfor %}
  </div>
{% endfor %}
like image 531
bcoughlan Avatar asked Dec 30 '11 10:12

bcoughlan


1 Answers

You're looking for the {% regroup %} tag, which does exactly what you want. It takes a sequence of items (it has to be ordered beforehand, which yours is) and a lookup and groups the sequence by that lookup.

view:

events = Event.objects.select_related.all()

template:

{% regroup events by date as events_by_date %}
{% for date in events_by_date %}
    <div class="content">
    <h1>{{ date.grouper|date:"d F Y" }}</h1>
    {% for event in date.list %}
        {% include "partials/event.html" %}
    {% endfor %}
    </div>
{% endfor %}

(Notice that the date format string is different; the equivalent of %B in strftime is F for the date filter).

like image 162
Ismail Badawi Avatar answered Oct 02 '22 12:10

Ismail Badawi