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.
On Thursday, April 20, 2017 at 4:35:36 PM UTC+1, Will Holmes wrote:
-- 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 django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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.
No comments:
Post a Comment