Wandering Thoughts archives


Why I wound up using Django

Eevee just wrote (and I just read) a good article on Python web development. It was an interesting experience for me, because a great deal of the article is about a middle level in Python webdev that I've basically skipped right over. I've worked at the level of CGI and WSGI and I've worked in the big framework land of Django, but I've never played around in the world of relatively simple and component-ized Python web frameworks that Eevee mostly talks about (to the extent that I merged them in with Django when I wrote about modern Python web app options). And that raises an obvious question: why did I wind up using Django instead of one of the smaller and simpler alternatives?

While I could say various things, the honest answer is twofold: good PR on Django's part and 'batteries included', with the first one being more important. The good PR insured that I knew of Django and indeed thought of it as the natural choice once I knew that I needed a framework. The batteries included nature meant that I was getting everything I needed in one place, pre-integrated for me, with no omissions that might have pulled me out to look at anything else.

Do I feel bad about falling for Django's PR and batteries included monolith? No. Not at all. While I have some sympathies to the smaller and leaner frameworks (I'm ordinarily a smaller is better person), I feel that frameworks are special in a way. The thing about frameworks is that they are only a means to an end, ie a working web app. Almost all web apps are small and undemanding enough that the differences between good enough frameworks are not important; any one of them will do. What really matters is getting your application written, and for that the inclusion of batteries matters a lot.

Let me be blunt. For most people selecting a framework, the last thing they want to do is then try to pick out a templating system, a database ORM layer, a forms handling package, and so on. This is especially so because all of those things are what really gets the work done for most projects; without them, a framework is only a skeleton that does, well, not very much (it's less a framework and more a request/response handling library) and provides very little help for your project. This means that including batteries by default is quite important in practice (even if it may cause political difficulties). I don't think that you have to make the default choice the only option, but if you want me to pay your framework much attention you need something that's pre-chosen and ideally pre-assembled for me; doing otherwise means that your framework simply requires too much additional time when there are other options.

Even if Django had not had the PR edge that it does, even if it had simply been one among a number of equally well known contenders, I think I would have chosen it purely for the batteries included nature. I had a project to get done and Django offered me a single solution for everything I needed so I could immediately jump into building my actual app.

python/WhyDjango written at 23:32:00; Add Comment

Counting your syndication feed readers

Suppose that your blog has a syndication feed, and you would like to know how many people are reading it. While you could just look at your web stats to see how many different people pull your feed, the numbers aren't you'll get won't be too useful. Some of those feed requests are from aggregators and not all aggregators report readership numbers to you (and some of them have no idea, for example planet-style aggregators that just put the result up on a web page), plus not everyone who pulls your feed is still actually reading your entries; you have to assume that a certain amount of feed subscriptions are just quietly rotting away unread.

(These effects compound, of course. I have no idea if Google Reader's reported numbers exclude people who are subscribed but not reading, for example.)

I will cut to the chase: the hack solution to this is images. You can crudely track actual entry readership by putting a (unique) image in your entry, one that you host, and then counting requests for it in your own logs. Of course this works best if you already write the sort of blog where you include images in your entries, either as part of them or simply for visual flavour and design. Otherwise people may start to wonder why your entries periodically include random images.

(There are all sorts of issues with this which make it only a crude measure. Carefully making the image uncacheable by proxies and serving cookies with it will help with some of them.)

There are at least three sorts of images you can use for this; little invisible 'web bug' images, more or less unimportant images that are just used to add visual appeal and design to entries, or images that are actual relevant parts of your entries. Setting aside the issue of being nice to your readers, the last choice is the pragmatically best one. If the images are actually an integral part of your entries your readers will make sure that they see them even in the face of feed reader issues (going so far as to visit your entry directly if necessary). Less important images can drop out without the readers caring (or even noticing), so you will undercount such people.

(Web bugs are especially likely to get screened out, of course. I wouldn't be surprised if some feed readers and aggregators do it automatically by now.)

My strong impression is that nothing other than real images inline in your entries will work reliably. Many aggregators and even feed readers apparently screen out JavaScript, much or all CSS including background images, and probably all sorts of other tricks. However screening out plain inlined images generally doesn't happen, partly because it degrades the reading experience too much to be popular.

PS: I'm sure this is well known in the part of the web world that cares about readership stats. I just feel like writing it down here for the record.

web/CountingFeedReaders written at 01:05:37; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.