Tangled Webs of Django Applications
Recently updated on
At Imaginary Landscape, we definitely enjoy leveraging the many open source applications that exist out in the wild. We also create some of our own open source applications, along with a few closed source applications that are either too customized for one particular customer, or for a number of other reasons dealing with clients and such. However, a constant problem arises with all of these different applications floating about. How do you deal with templates and media?
Sure, a couple of different ideas were batted around. Pinax has their way of handling all of the different media, which mainly seems to involve a management command that syncs all the media to a specific location. We've used django-staticmedia which was created by one of our employees, which adds a mount point for media in specific applications. Each have their merits, I suppose. I've always had the habit of just manually rsyncing media to the location I want it, and that's worked pretty well for me overall.
Some people go so far as to say that you shouldn't include media with your project, as that makes it inherently less pluggable. For instance, I may want to use your blogging application, but I don't necessarily want my blog to look exactly like yours. I'm going to end up overriding your templates, changing your CSS, and so on, so why bother including it? The counter-point to that is, what if I just want to get up and running quickly? I found django-registration, the first application I really played with, to be rather confusing due to there not being any example templates. Obviously I figured it out, but some samples to get me rolling in my Django infancy would have be great (counter-point: maybe I actually learned something this way, and I wouldn't have if everything was just handed to me).
So how do we actually fix the problem? Personally, I like the approach django-staticmedia takes. It basically works much like the template loaders that load up all the templates from your installed applications. You tell it where to mount the media, and then you tell Apache/nginx to serve that location. The only problem is you have to tell nginx where that location is for every application that you use, so that's not quite ideal. However, if we could have something that works similar to the template system, that'd be amazing, but at the same time that's somewhat out of the Django core's scope.
Ultimately, I think changing our way of looking at applications might possibly be the most beneficial. So many applications in the Django community seem to push so hard for being "pluggable", and I worry that eventually that has to come with some cost. For instance, when I developed YaBa, I wanted it to work "out of the box", sort of like a Wordpress alternative. I wasn't too terribly concerned with people plugging it into their existing infrastructure, because those weren't my target audience. Instead I was shooting for the people that grab a small hosting account, install Wordpress, and start writing blog entries. The premise was to be able to install YaBa, configure a few minor settings, and get started on doing what you wanted to do in the first place, blog. I wasn't shooting for "Pluggable Application", I simply wanted to make an application.
Sure, we fast forward to today, and YaBa is far more pluggable now. I've generalized some things, cleaned up the code, and it's fairly pluggable (except for that whole media problem) all without any major sacrifices. The big exception being, it's harder for someone who doesn't want to know anything about Django to install now. Maybe the best idea is just stick with the current status quo. If you want to include media in order to make your application work, I say more power to you, if the end-user doesn't want it, let them deal with it. I'm comfortable with just manually copying media files to my static media path on installs and upgrades.
However, I do ask this one favor application developers: Please link to your media and templates in your application in a sensible, application specific way. I don't want to inadvertantly nuke my CSS, because you named yours the same, and I blindly rsynced (yeah, my problem, not yours). Instead how about:
/media/APP_NAME/*
That way I don't trample my stuff, and you still get to include your media, and the world lives on in happiness. Afterall, you already structure your templates that way, why wouldn't you do the media the same way?