Django attaching events to days in a calendar?

Question:

I have built a basic calendar which generates a table with the current month (taken from the URL) using the built-in calendar.Calendar function, but I would like to attach events to the days that are generated. What would be the best way to do that?

Currently in my views:

def view_calendar(request, year=None, month=None):
    events = Event.objects.filter(creator=request.user)
    new_event_form = EventForm()
    now = datetime.date.today()
    if year:
        year = int(year)
    else:
        year = now.year
    if month:
        month = int(month)
    else:
        month = now.month

    cal = calendar.Calendar(calendar.SUNDAY)
    month_days = cal.monthdatescalendar(year, month)

    args = {'events': events, 'month': month, 'year': year, 'month_days': month_days}
    args.update(csrf(request))
    args['new_event_form'] = new_event_form
    return render(request, 'calendar.html', args)

And in my template I can call the weeks and days like this:

<table cellpadding="3" width="100%">
    <tr>
        <td>Sunday</td>
        <td>Monday</td>
        <td>Tuesday</td>
        <td>Wednesday</td>
        <td>Thursday</td>
        <td>Friday</td>
        <td>Saturday</td>
    </tr>
    {% for week in month_days %}
        <tr>
            {% for day in week %}
                <td>
                    {{day|date:"j"}}<br />
                </td>
            {% endfor %}
        </tr>
    {% endfor %}
</table>

What I would love to do is have something like this in my views:

for week in month_days:
        for day in week:
            day['events'] = list(Event.objects.filter(creator=request.user, start_date=day))

But I get this error:
TypeError: ‘datetime.date’ object does not support item assignment

Is there a way I can easily convert these days to objects that support item assignment so I can attach Events to the days and add them to the calendar?

Asked By: Jason Boyce

||

Answers:

You can’t use date type object like dict.

    day['events'] = xxx

Instead you could do something like

    events = [(day, Event.objects.filter(creator=request.user,  start_date=day)) 
              for day in [week for week in month_days]]

and use it in the template

    {% for week in events %}
    <tr>
        {% for day, events in week %}
            <td>
                {{day|date:"j"}}<br />
                {% for event in events %}
                     {{ event }}<br/>
                {% endfor %}

            </td>
        {% endfor %}
    </tr>
   {% endfor %}
Answered By: delta32

I got it working based off of delta32’s suggestion. I needed to create an empty Events dictionary, then append each of the weeks to the events dictionary after running through my foor loop. That leaves me with:

events = []
for week in month_days:
    week_events = [(day, TSEvent.objects.filter(created_by=request.user, date_start=day)) for day in week]
    events.append(week_events)

Then, in the calendar template:

{% for week in events %}
<tr>
    {% for day, events in week %}
        <td>
            <a href="/ts/calendar/{{day|date:"Y"}}/{{day|date:"m"}}/{{day|date:"j"|leading_zeros:"2"}}/">
                {{day|date:"j"}}
            </a>
            <br />
            {% for event in events %}
                <p><a href="/apps/timesweet/events/{{event.id}}/"><b>{{event.name}}</b></a></p>
            {% endfor %}
        </td>
    {% endfor %}
</tr>
{% endfor %}
Answered By: Jason Boyce
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.