- Author:
- sandinmyjoints_
- Posted:
- June 13, 2011
- Language:
- Python
- Version:
- 1.2
- Score:
- 0 (after 2 ratings)
I wanted a simple way to display events for a given month in a calendar, so I adapted some code to write a template tag. Event
is the model class, and it needs to have a date_and_time
field. Each event is part of a Series
, so in the view you can filter events by which series, or display events for all known Series.
Full explanation and description of simple Django event calendar template tag.
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | ##### Here is the template tag code. It goes in a file named
# "event_tags.py" in a subdirectory of your app called "templatetags".
#####
from calendar import HTMLCalendar
from django import template
from datetime import date
from itertools import groupby
from django.utils.html import conditional_escape as esc
register = template.Library()
def do_event_calendar(parser, token):
"""
The template tag's syntax is {% event_calendar year month event_list %}
"""
try:
tag_name, year, month, event_list = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires three arguments" % token.contents.split()[0]
return EventCalendarNode(year, month, event_list)
class EventCalendarNode(template.Node):
"""
Process a particular node in the template. Fail silently.
"""
def __init__(self, year, month, event_list):
try:
self.year = template.Variable(year)
self.month = template.Variable(month)
self.event_list = template.Variable(event_list)
except ValueError:
raise template.TemplateSyntaxError
def render(self, context):
try:
# Get the variables from the context so the method is thread-safe.
my_event_list = self.event_list.resolve(context)
my_year = self.year.resolve(context)
my_month = self.month.resolve(context)
cal = EventCalendar(my_event_list)
return cal.formatmonth(int(my_year), int(my_month))
except ValueError:
return
except template.VariableDoesNotExist:
return
class EventCalendar(HTMLCalendar):
"""
Overload Python's calendar.HTMLCalendar to add the appropriate events to
each day's table cell.
"""
def __init__(self, events):
super(EventCalendar, self).__init__()
self.events = self.group_by_day(events)
def formatday(self, day, weekday):
if day != 0:
cssclass = self.cssclasses[weekday]
if date.today() == date(self.year, self.month, day):
cssclass += ' today'
if day in self.events:
cssclass += ' filled'
body = ['<ul>']
for event in self.events[day]:
body.append('<li>')
body.append('<a href="%s">' % event.get_absolute_url())
body.append(esc(event.series.primary_name))
body.append('</a></li>')
body.append('</ul>')
return self.day_cell(cssclass, '<span class="dayNumber">%d</span> %s' % (day, ''.join(body)))
return self.day_cell(cssclass, '<span class="dayNumberNoEvents">%d</span>' % (day))
return self.day_cell('noday', ' ')
def formatmonth(self, year, month):
self.year, self.month = year, month
return super(EventCalendar, self).formatmonth(year, month)
def group_by_day(self, events):
field = lambda event: event.date_and_time.day
return dict(
[(day, list(items)) for day, items in groupby(events, field)]
)
def day_cell(self, cssclass, body):
return '<td class="%s">%s</td>' % (cssclass, body)
# Register the template tag so it is available to templates
register.tag("event_calendar", do_event_calendar)
##### Here's code for the view to look up the event objects for to put in
# the context for the template. It goes in your app's views.py file (or
# wherever you put your views).
#####
def named_month(month_number):
"""
Return the name of the month, given the number.
"""
return date(1900, month_number, 1).strftime("%B")
def this_month(request):
"""
Show calendar of events this month.
"""
today = datetime.now()
return calendar(request, today.year, today.month)
def calendar(request, year, month, series_id=None):
"""
Show calendar of events for a given month of a given year.
``series_id``
The event series to show. None shows all event series.
"""
my_year = int(year)
my_month = int(month)
my_calendar_from_month = datetime(my_year, my_month, 1)
my_calendar_to_month = datetime(my_year, my_month, monthrange(my_year, my_month)[1])
my_events = Event.objects.filter(date_and_time__gte=my_calendar_from_month).filter(date_and_time__lte=my_calendar_to_month)
if series_id:
my_events = my_events.filter(series=series_id)
# Calculate values for the calendar controls. 1-indexed (Jan = 1)
my_previous_year = my_year
my_previous_month = my_month - 1
if my_previous_month == 0:
my_previous_year = my_year - 1
my_previous_month = 12
my_next_year = my_year
my_next_month = my_month + 1
if my_next_month == 13:
my_next_year = my_year + 1
my_next_month = 1
my_year_after_this = my_year + 1
my_year_before_this = my_year - 1
return render_to_response("cal_template.html", { 'events_list': my_events,
'month': my_month,
'month_name': named_month(my_month),
'year': my_year,
'previous_month': my_previous_month,
'previous_month_name': named_month(my_previous_month),
'previous_year': my_previous_year,
'next_month': my_next_month,
'next_month_name': named_month(my_next_month),
'next_year': my_next_year,
'year_before_this': my_year_before_this,
'year_after_this': my_year_after_this,
}, context_instance=RequestContext(request))
##### Here is the code to load and use the template tag in a template.
{% load event_tags %}
<div id="calendar">
{% event_calendar year month event_list %}
</div>
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Please login first before commenting.