Fixed this by just not using groupby. So far I just have a slightly
long-winded work around that formats the data in the same way as groupby
but includes all days in in between, and including, the start date and end
date.
def group_by_day(self, events, month):
return_dict = {}
for event in events:
if event.end_date != None:
number_days = event.end_date - event.start_date
day_range = [event.start_date + timedelta(
days=i) for i in range(number_days.days + 1)]
for date in day_range:
if date.month == month:
if date.day in return_dict:
return_dict[date.day].append(event)
else:
return_dict[date.day] = [event]
else:
if event.start_date.day in return_dict:
return_dict[event.start_date.day].append(event)
else:
return_dict[event.start_date.day] = [event]
return return_dict
On Thursday, April 20, 2017 at 4:35:36 PM UTC+1, Will Holmes wrote:
>
> Hi guys,
>
>
> I am using django to develop a calendar web app where users can create events
> that are then displayed on a month by month view.
>
>
> I have written a custom template tag that takes Python's HTMLCalendar
> formatmonth function and overlays events that are on that day.
>
>
> It is currently set up to take the start date of the event directly from each
> event and then use groupby to group each event by the day of the month in a
> dictionary. These can then be overlaid on the calendar. This, however, is not
> particularly useful if an event occurs over multiple days.
>
>
> I want to find a way of taking each of the days the event occurs over, start
> date to end date, before returning a similar dictionary. However, I cannot
> seem to get this to work whichever way I try it. Here is the group_by_day
> function that currently groups the events by start date:
>
>
> #Here is where the code groups events for the relevant month day
> def group_by_day(self, events):
> field = lambda event: event.start_date.day
> return dict(
> [(day, list(items)) for day, items in groupby(events, field)]
> )
>
>
> Can anyone suggest a way round this problem?
>
>
> If you need any more information please let me know. The project can be
> viewed in entirety at https://github.com/Willrholmes01/organiser.
>
>
> Below is the entire template tag:
>
>
> register = template.Library()
>
> def do_month_calendarify(parser, token):
> # Take the tag input from the template and format
> # Template syntax is {% calendarify year month %}
> 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 CalendarifyNode(year, month, event_list)
>
> class CalendarifyNode(template.Node):
>
> 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:
> my_year = self.year.resolve(context)
> my_month = self.month.resolve(context)
> my_event_list = self.event_list.resolve(context)
> cal = EventCalendar(my_event_list)
> return cal.formatmonth(
> int(my_year), int(my_month))
> except ValueError:
> return "%s, %s, %s" % (my_month, my_year, my_event_list)
>
> class EventCalendar(HTMLCalendar):
> # Use Python's HTMLCalendar and put user events over top
> def __init__(self, events):
> super(EventCalendar, self).__init__()
> self.events = self.group_by_day(events)
>
> def formatday(self, day, weekday):
> if day != 0:
> cssid = self.cssclasses[weekday]
> cssclass = "daybox"
> if date.today() == date(self.year, self.month, day):
> cssid += ' today'
> if day in self.events:
> cssid += ' filled'
> body = ['<ul>']
> for event in self.events[day]:
> body.append('<li>')
> body.append('<a id="event_%d" href="%s">'
> % (event.id, event.get_absolute_url
> ()))
> body.append(esc(event.title))
> body.append('</a></li>')
> body.append('</ul>')
> return self.day_cell(
> cssclass, cssid, '<span class="dayNumber">%d</span>
> %s' % (
> day, ''.join(body)))
> return self.day_cell(
> cssclass, cssid, '<span
> class="dayNumberNoReadings">%d</span>' % (day))
> return self.day_cell('nodaybox', 'noday', ' ')
>
> def formatmonth(self, year, month):
> self.year, self.month = year, month
> return super(EventCalendar, self).formatmonth(year, month)
>
> #Here is where the code groups events for the relevant month day
> def group_by_day(self, events):
> field = lambda event: event.start_date.day
> return dict(
> [(day, list(items)) for day, items in groupby(events, field)]
> )
>
> def day_cell(self, cssclass, cssid, body):
> return '<td class="%s" id="%s">%s</td>' % (cssclass, cssid, body)
>
> register.tag('calendarify', do_month_calendarify)
>
>
>
>
>
>
>
--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/a9c0e243-5b21-486e-9fa3-5f0d2ba3fbad%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.