1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 | # Template tag
from datetime import date, timedelta
from django import template
from myapp.models import Event # You need to change this if you like to add your own events to the calendar
register = template.Library()
from datetime import date, timedelta
def get_last_day_of_month(year, month):
if (month == 12):
year += 1
month = 1
else:
month += 1
return date(year, month, 1) - timedelta(1)
def month_cal(year, month):
event_list = Event.objects.filter(start_date__year=year, start_date__month=month)
first_day_of_month = date(year, month, 1)
last_day_of_month = get_last_day_of_month(year, month)
first_day_of_calendar = first_day_of_month - timedelta(first_day_of_month.weekday())
last_day_of_calendar = last_day_of_month + timedelta(7 - last_day_of_month.weekday())
month_cal = []
week = []
week_headers = []
i = 0
day = first_day_of_calendar
while day <= last_day_of_calendar:
if i < 7:
week_headers.append(day)
cal_day = {}
cal_day['day'] = day
cal_day['event'] = False
for event in event_list:
if day >= event.start_date.date() and day <= event.end_date.date():
cal_day['event'] = True
if day.month == month:
cal_day['in_month'] = True
else:
cal_day['in_month'] = False
week.append(cal_day)
if day.weekday() == 6:
month_cal.append(week)
week = []
i += 1
day += timedelta(1)
return {'calendar': month_cal, 'headers': week_headers}
register.inclusion_tag('agenda/month_cal.html')(month_cal)
"""
Put this in your template (in my case agenda/month_cal.html):
<table class="cal_month_calendar">
<tr>
{% for day in headers %}
<th>{{ day|date:"D"|slice:":2" }}</hd>
{% endfor %}
</tr>
{% for week in calendar %}
<tr>
{% for day in week %}
<td{% if not day.in_month %} class="cal_not_in_month"{% endif %}>{% if day.event %}<a href="/calendar/{{ day.day|date:"Y/m" }}/">{{ day.day|date:"j" }}</a>{% else %}{{ day.day|date:"j" }}{% endif %}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
"""
|
Comments
I'm having problems getting this to work - I'm not entirely sure where the tag gets the year/month from. Can you help?
#
mrben,
You can use this template tag by putting this in your template:
{% month_cal 2007 5 %}
This would render the calendar for May 2007. Of course you can use variables instead of hardcoded year/month.
Hope that helps!
#
Hmmm - well, things are different anyway. First I got an AttributeError from line 42 - it didn't like date() as a method of a datetime object - and now when I load it it manages to load my events page (ie the same page) in the space where the calendar should be.
I'll keep fiddling....
#
I've made a couple changes to the code, that others may find useful:
This will draw the calendar dynamically based on the current month and year. Thus, you can call the variable in the template with no arguments or 2:
Also, your calendar draws the beginning of the week with Monday. Some prefer Sunday. This was easy with the following code change:
and
#
Is it possible to view an example of the use of this?
#
The calendar module (http://www.python.org/doc/current/lib/module-calendar.html) provides a function called monthrange which also handles leap years and should be used instead of get_last_day_of_month
#
Can you put more instruction how to put all of the code into separate *.py files and html file, I'm new to this project
#