The Visual Bit
As I mentioned in a previous article, the first requirement issued by Her Indoors was to select pictures by a date range. Not an unreasonable request, and I rapidly added a first version to the toolbar, so that you can refine all views (hopefully!) by date range. The whole photo-collection, album content, folder content — all should be filterable by dates.
After a while, I started to see wider possibilities. A calendar view in its own right starts to make sense. Firstly, you’d have a more intuitive feel for the period of time if the whole picture gallery could be seen as a calendar. Secondly, you might want to refine that view with your own styles and then just dump the whole view as a PDF, desktop-publishing file or other format and use the page as a calendar as-is.
I now have a first draft of the Calendar view up and visible, as above. It’s far from polished, please note. You’ll rapidly notice that the day-dates don’t line up with the correct weekday. That’s for the next bug-fixes. You’ll also notice that there’s an infuriating variation in the widths of the day columns, at least if you are using Chromium. For some reason the header with the month name, a cell with a colspan of 7 for those who wish to know, is entraining the first day-column on the lower rows according to the width of the month-name text. Hoping to fix that, too. Detail, details!
What works, huzzah, is that you can see which months currently have pictures with an assigned date. You can click on the month and it will take you to the month view where you can see the individual days. You can then hit a day and it will, fingers crossed, show you a “Pictures” view of the shots from that day. Not bad for a week’s work on the side while also studying for a certification and cooking huge amounts of Mediterranean food.
The Technical Bit
This seems to be a good place to start explaining how a user cloning the project off GitHub could go about adding their own functionality, as the Calendar view covers most of it. So here goes:
In the urls.py file, you’ll need a mapping to the view. As you can see, I’m using a class-based view called CalendarView, cleaving as closely as possible to the rule of least astonishment. That view is defined in views.py. Here’s what it looks like, and bear in mind that it is a DERIVED class, based on a lot of other code that will be explained another time:
The ellipses on lines 740 and 759 are to paper over some fairly ugly code with several nested loops and trivial lists. Not only is this an offence against the developer’s aesthetic, it also takes up too much space. A refactoring is planned… Python Django makes it deliberately hard to do complex conditional logic in a template, so it’s best to do it in the view. What I am basically doing behind the ellipses is packing the photo URLs and their corresponding dates into a nested dictionary of groups of years, each year containing groups of months, each month containing groups of seven days. These last DO NOT yet line up with calendar weeks, as mentioned above. As for the individual methods:
- build_calendar is a utility to build the nested structure described above.
- get_context_data marshals other information that the HTML template will need to render the page, such as the day names for a particular day index. This will be important later for localisation.
- get_queryset is a standard method for a class-based View in Django, and calls up that nested structure for the view to iterate through in rendering the page.
- form_valid validates any arguments defining a date range, which will become important in looking up a calendar section from other pages.
In filters.py, in the templatetags directory, there are a couple of utilities to get formatted date parts for the template to render:
Lastly, there’s the HTML template itself.
You’ll see that this contains a mixture of HTML and Django template markup. It takes some getting used to, but is not that complex. There are also some styles in there which I have not yet taken out into a CSS static file.
So, that is a very broad outline of how generally to add a view using Python Django, and specifically how to add your own to homePIX. I’ve left out the CSS, and I can promise you that this is where the devil hides in the details. Getting the calendar to look just the way you want it is much harder than just adding a new view. (Or perhaps you’re all talented web designers and it’s trivial for you, but the Python code is pure Klingon.)
The list of TODOs is prodigious. I still have to clean up the code, add documentation markup, deal with localisation, finish off the formatting and alignment. Then I have to make it possible for a user following up with their own site to personalise it as easily as possible. That involves nailing down the customisation of Bootstrap, among other things.
So I’d like to start a conversation. Let me know what you think of the calendar view and what you want to have added. You can say, “But I wanted a zoomable map,” and I’ll say, yes, but that’s on another list. What I’d really like now is for someone to start using homePIX to build their own site. Then we’ll see if we can take back the stock photography market for photographers.