Here is what happens when you browse to http://www.example.com/eventcal/2007/08/ The URL is split into host/path, path is used to find a view: In this case, it gets done in 2 steps. the "eventcal" part is used to route things into the 'calendar app' which lives in eventcal: {{{ line 9 of ./urls.py: (r'^eventcal/', include('eventcal.urls')), line 7 of ./eventcal/urls.py (r'^(?P\d{4})/(?P\d{2})/$', 'month_index'), }}} The parameters are extracted: year and month - (?P\d{4}) = decimal(4) And calls month_index( request, year, month ) (it can also be called with no year/month, which defaults to the current date.) {{{ #!python def month_index(request, year = None, month = None): now = datetime.today() if not year: year = now.year if not month: month = now.month year = int(year) month = int(month) # Make sure we have a sane date. # A munged URL could give us month 13 try: cal_date = date(year, month, 1) except ValueError: raise Http404 # Week starts on Sunday c=calendar.Calendar(calendar.SUNDAY) # get all the dates that will be displayed, # including the tail and head of previous/next months. # (a list of weeks, each week is a list of 7 dates.) dates=c.monthdatescalendar(year, month) # array, ['Monday', 'Tuesday'.. 0 is Mon. ## daynames=calendar.day_name # make list, cuz I can't figure out how to use the array in the template. # Use the first week of the calandar, which is handy # because it makes sure the week starts on the weekday we want it to # (like Sunday) daynames= [ calendar.day_name[d.weekday()] for d in dates[0] ] # get Events from the DB that are in the specified month. # [0][0] = first day of first week, [-1][-1], last day of last week. # so start/end of the range being displaied. events = Event.objects.filter(eventdate__range=(dates[0][0],dates[-1][-1])) # some fluf to make the page usable prev_month=(cal_date+relativedelta(months=-1))# .month next_month=(cal_date+relativedelta(months=+1))# .month return render_to_response('month_index.html', locals()) }}} render_to_response() takes a template file month_index.html and a bunch of vars (easy way: pass all the local vars) and returns browser ready HTML. I should probably not use .html for these files, cuz they aren't; but all the cool people use .html, so I'll fight that battle some other day. Template commands used here: {# X #} one line comments. {% comment %}X X X...{% endcomment %} multi line comment. {% extends X %} - kinda like subclass X. kinda like #include if you don't pay attention too close. but more like subclassing because {% block Y %} defined in X can be overridden (replaced) if it is redefined in the current code. in this case, main.html defines the 'stuff that will be on all pages' including some placeholders for headings and content, and month_index.html defines the headings and content. I can't figure out if it really is subclassing, or just similar. {{ X }} - expression evaluation - think VFPs <> text merge. X is evaluated, result is put in the HTML. pipe char | is used like unix filters to format the results. /{{ prev_month|date:"Y/m" }} prev_month is a date. |date:"Y/m" makes a string out of the year/month. so 6/1/2007 becomes "2007/6" which makes a nice URL for handing into the top of this process. prev {% for week in dates %} {% endfor %} basic for loop. {% ifequal day now.date %} {% endifequal %}> it's IF, but for some reason they made the operator? part of the command instead of "IF X" where X is a boolean. no clue why. possibly for speed. {{{ #!django {# month_index.html #} {% extends "main.html" %} {% block css %} {% endblock %} {% block title %}Calendar{% endblock %} {% block list_title %}Events{% endblock %} {% block content %} {# Display month/year and links to previous/next month. #}

< {{ cal_date|date:"F" }} {{ cal_date.year }} >

{# Make the grid of days #} {# headers: Monday, Tuesday.... #} {% for dayname in daynames %} {% endfor %} {# What we came here for: the days and events. #} {% for week in dates %} {% for day in week %} {% endfor %} {% endfor %}
{{ dayname }}
{{ day|date:"j" }}

{% for event in events %} {% ifequal event.eventdate day %}

  • {{ event.title }}
  • {% endifequal %} {% endfor %}


    {# List the events in a list. #} {% if events %}
      {% for event in events %}
    • {% ifequal event.eventdate.month month %} {{ event.eventdate|date:"l j" }} {% else %} {{ event.eventdate|date:"F j" }} {% endifequal %} {{ event.title }}
    • {% endfor %}
    {% else %}

    No activities this month.

    {% endif %}
    {% endblock %} }}} Pretty much all main does is define the 'menu' that will be on all pages. {{{ #!django {# main.html #} {% extends "base.html" %} {% block css %}{% endblock %} {% block title %}Logged in{% endblock %} {% block headtags %} {% endblock %} {% block content %}{% endblock %} {% block foottags %} Event Calendar Admin Messages logout {% endblock %} }}} base.html is the top most file on the food chain. {{{ #!django {# base.html #} My Great Site {% block title %}{% endblock %} {% block css %}{% endblock %}
    {% block content %}{% endblock %}

    • phone number here
    }}}