I’m trying to program a calendar app using Django and I can’t seem to get it to show the days of the month. For monthly views in views.py I have:
from datetime import date, datetime, timedelta
import calendar
@login_required
def month(request, year, month, change=None):
"""Listing of days in `month`."""
year, month = int(year), int(month)
# apply next / previous change
if change in ("next", "prev"):
now, mdelta = date(year, month, 15), timedelta(days=31)
if change == "next": mod = mdelta
elif change == "prev": mod = -mdelta
year, month = (now+mod).timetuple()[:2]
# init variables
cal = calendar.Calendar()
month_days = cal.itermonthdays(year, month)
nyear, nmonth, nday = time.localtime()[:3]
lst = [[]]
week = 0
# make month lists containing list of days for each week
# each day tuple will contain list of entries and 'current' indicator
for day in month_days:
entries = current = False # are there entries for this day; current day?
if day:
entries = Entry.objects.filter(date__year=year, date__month=month, date__day=day)
if day == nday and year == nyear and month == nmonth:
current = True
lst[week].append((day, entries, current))
if len(lst[week]) == 7:
lst.append([])
week += 1
return render_to_response("cal/month.html", dict(year=year, month=month, user=request.user, month_days=lst, mname=mnames[month-1]))
For the yearly template, I have:
{% extends "cal/base.html" %}
{% block content %}
<a href="{% url cal.views.main year|add:'-3' %}"><< Prev</a>
<a href="{% url cal.views.main year|add:'3' %}">Next >></a>
{% for year, months in years %}
<div class="clear"></div>
<h4>{{ year }}</h4>
{% for month in months %}
<div class=
{% if month.current %}"current"{% endif %}
{% if not month.current %}"month"{% endif %} >
{% if month.entry %}<b>{% endif %}
<a href="{% url cal.views.month year month.n %}">{{ month.name }}</a>
{% if month.entry %}</b>{% endif %}
</div>
{% if month.n == 6 %}<br />{% endif %}
{% endfor %}
{% endfor %}
{% endblock %}
That displays the months in a year. But when I click on the month, it doesn’t display the days.
For the monthly template, I have:
{% extends "cal/base.html" %}
{% block content %}
<a href= "{% url cal.views.month year month "prev" %}"><< Prev</a>
<a href= "{% url cal.views.month year month "next" %}">Next >></a>
<h4>{{ mname }} {{ year }}</h4>
<div class="month">
<table>
<tr>
<td class="empty">Mon</td>
<td class="empty">Tue</td>
<td class="empty">Wed</td>
<td class="empty">Thu</td>
<td class="empty">Fri</td>
<td class="empty">Sat</td>
<td class="empty">Sun</td>
</tr>
{% for week in month_days %}
<tr>
{% for day, entries, current in week %}
<!-- TD style: empty | day | current; onClick handler and highlight -->
<td class= {% if day == 0 %}"empty"{% endif %}
{% if day != 0 and not current %}"day"{% endif %}
{% if day != 0 and current %}"current"{% endif %}
{% if day != 0 %}
onClick="parent.location='{% url cal.views.day year month day %}'"
onMouseOver="this.bgColor='#eeeeee';"
onMouseOut="this.bgColor='white';"
{% endif %} >
<!-- Day number and entry snippets -->
{% if day != 0 %}
{{ day }}
{% for entry in entries %}
<br />
<b>{{ entry.creator }}</b>: {{ entry.short|safe }}
{% endfor %}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<div class="clear"></div>
</div>
{% endblock %}
I don’t think it’s a problem with the way I’ve constructed my monthly view. Rather, I think it’s a problem with the way I’ve linked my yearly template to my monthly template. I’m new to Django and programming in general, so if anyone can point me in the right direction, I’d greatly appreciate it.
Edit:
Here is my urlconf in app/urls.py:
from django.conf.urls import patterns, include, url
from cal.views import main
from cal.views import month
from cal.views import day
urlpatterns = patterns('',
(r'^(\d+)/$', main),
(r'', main),
(r'^month/(\d+)/(\d+)/(prev|next)/$', month),
(r'^month/(\d+)/(\d+)/$', month),
(r'^month$', month),
(r'^day/(\d+)/(\d+)/(\d+)/$', day),
)
Main handles the template for the yearly view.
So I’m guessing that
mainis the view that produces the year/month list. The trouble is that the second regex for that matches everything, because you don’t anchor it. You need this:so that it only matches the string where there is nothing between the start and the end – ie the empty string.