Distributing your Django Projects
Django is my framework of choice for virtually any problem the web can throw at me, and I've had a lot of fun working on my own projects using it. Unfortunetely, I've been hitting some issues with it. I might not even be talking about Django here, but Python itself, or may be even frameworks in general. The problem is how you distribute your projects.
When you distribute a project, as in attempt to make easy for other people to run your code, you need to make a few considerations.
- Initially downloading/installing and its dependencies
- Customising and updating
Installation and Dependencies
Python adopts a modular approach, with heavy use of namespacing to make organising your code very easy, as well as promoting the DRY principle. This is great, because it generally means as a developer I can grab someone else's library and pull it in to my own apps. But what happens when I want to share my project? Does whoever chooses to try out my project also need to download the library? What happens if they get a newer, incompatible version of the library; am I oblidged to make my code work with the latest version of the library? What if two apps needs different versions, do we need PYTHONPATH wizardary to sort it all out?
At Europython this issue was briefly touched upon in a talk. With modern broadband speeds, and the relative size of a code base it was suggested that its only logical to actually include any dependencies within your project. But what does that mean for Django projects? Should there be a dependency package within each project in which the developer specifies which versions to use? How would that work if you need PIL?
So here's another scenario. I have a website with a blog, and a gallery. They both make use of a great paginator someone's written. I decide that I will distribute the source of my website and call it a CMS.
Because I don't want the paginator to belong to my gallery app, or blog app, exclusively I store it in myproject.dependencies.paginator
Someone sees my gallery and decides they only want this. Python's modular approach should mean they can just grab the gallery package, but they'll also need to work out the paginator dependency. This means we've not really solved our original problem. I could, of course, have the paginator in both the blog and the gallery, but this would cause repeated code and would be seen as a major no-no.
I'm not entirely sure how to solve this issue, I'm open to any suggestions! Is this a Django related problem, or a general side-effect of working with frameworks? How do other frameworks deal with dependencies and external library? Are framework based projects even possible to distribute problem free?
Customising and updating
By customising, I actually mean "skinning to your environment". Were you to download this website you'd no doubt want to be able to customise the look and feel of it. But what happens when you want to update? Are your templates going to be overwritten by changes to the main codebase?
Thankfully this is quite a simple problem to solve in Django. Have a look in my repository, you'll see that I have a "personal_website", and a "danux" folder. Personal website is the core of the website, with all the models and views, essential stuff that if you update you will want. Then there's danux, which is actually my website. This will never need updating, it contains site specific settings, templates and media. I'll also be adding a "default" soon, which will be a plain, un-branded theme that can be used on personal_website. This will be my starting point for all future project, and I currently have a number of sites actually running off a single, "personal_website" codebase.
There's a few things you need to consider though:
- Make sure the settings file includes the master settings file
- Things such as dumping data to fixtures will not work if your manage.py is not in the same package as your core code