There’s a large body of technical information out there about content management systems and frameworks, but not much written specifically for decision-makers. Programmers will always have preferences, but it’s the product managers and supervisors of the world who often make the final decision about what platform on which to deploy a sophisticated site. That’s tricky, because web platform decisions are more-or-less final — it’s very, very hard to change out the platform once the wheels are in motion. Meanwhile, the decision will ultimately be based on highly technical factors, while managers are often not highly technical people.
This document aims to lay out what I see as being the pros and cons of two popular web publishing platforms: The PHP-based Drupal content management system (CMS) and the Python-based Django framework. It’s impossible to discuss systems like these in a non-technical way. However, I’ve tried to lay out the main points in straightforward language, with an eye toward helping supervisors make an informed choice.
This document could have covered any of the 600+ systems listed at cmsmatrix.org. We cover only Drupal and Django in this document because those systems are highest on the radar at our organization. It simply would not be possible to cover every system out there. In a sense, this document is as much about making a decision between using a framework or using a content management system as it is between specific platforms. In a sense, the discussion about Drupal and Django below can be seen as a stand-in for that larger discussion.
Disclosure: The author is a Django developer, not a Drupal developer. I’ve tried to provide as even-handed an assessment as possible, though bias may show through. I will update this document with additional information from the Drupal community as it becomes available.
Systems Make Assumptions
Every web shop has its favorite tools and languages. Settling on just a few keeps toolchains, deployment, and development workflows sane. At both the UC Berkeley Graduate School of Journalism and the Knight Digital Media Center, we’ve settled on a mix of:
- WordPress for basic sites and “modest” online publications
- Django for sites with more complex needs or non-standard data models
For example, it makes sense to build student magazines, handbooks, FAQs, and blogs with WordPress. But it’s simply not possible to build an equipment checkout system, or a course evaluation system, or a student/faculty/staff directory with WordPress — not while trying to preserve your sanity. That’s because WordPress assumes so much about the structure of your data — it thinks every piece of content has a title, a summary, an author, etc. Start to veer away from that basic data structure and you find yourself quickly needing a platform that doesn’t make assumptions about how things should be done. For those kinds of problems, we use Django.
Meanwhile, there’s a lot of Drupal momentum on the UC Berkeley campus. In fact, there’s a lot of Drupal momentum all over the world — e.g. the recent move of whitehouse.gov to Drupal. And with that momentum comes questions from supervisors.
“Why aren’t we using Drupal?”
To be clear on terms:
- WordPress is a simple content management system.
- Drupal is an advanced content management system.
- Django is a framework.
Frameworks operate at a lower level than CMSs, and provide less of a turnkey experience for basic sites. In contrast, a framework is a box of parts from which you build your dream CMS – the CMS that precisely fits your organization’s data model and workflow. But the lines aren’t always so clear. Django comes with a self-generating administrative interface that’s so good and so user-friendly that we find it works fine as the CMS for the vast majority of projects we work on. The self-generating administrative interface can be tweaked and customized, or ignored altogether. It’s an optional component – you’re free to use it, modify it, or ignore it completely and write your own CMS on top of the framework.
On the other end of the spectrum, Drupal has some framework-like aspects to it. It’s been said that “Django is a framework with CMS-like tendencies, while Drupal is a CMS with framework-like tendencies.” So before you protest that I’m comparing apples and oranges, remember that in real life, the lines are blurry, and that apples and oranges can be compared, if what you intend is to compare types of fruit.
Every assumption made by a platform can either be a time-saver or an obstacle when it comes time for your site to grow or evolve, depending on:
- The ways you want that evolution to happen
- The skill of your developers
By their nature, frameworks are more flexible than CMSs. They make NO assumptions about the shape of your content, the Ajax system you might want to use, which rich text editor to present to your content people, etc.
Here are some of the key architectural points that matter to us when selecting a publishing platform, with pros and cons for Drupal and Django. I’ve sprinkled in some comments and feedback from members of the Django developer community (relevant comments from the Drupal development community will be included as well).
Python (the language on which Django is built) is extremely object-oriented, and thus so is Django. This means that data objects, querysets, variables, templates and arguments can be passed around in the codebase easily. This makes it easier to reduce or completely eliminate redundant code (Django subscribes to the DRY principle).
Drupal is generally not object-oriented. However, Drupal developer “catch” adds:
Drupal 7â€™s field and entity APIs are a step towards an ORM. Drupal’s database layer and many other subsystems including contributed modules like Views are object oriented to various extents.
Django uses the model-view-controller methodology (going by the name MTV in Django-land). This means that in Django, developers have almost complete separation of logic (programming), data structure, and display logic. MVC/MTV has emerged as a core aspect of modern programming practice.
Django is MVC from the ground up.
Django is famed for its super-clean, inheritance-based templating system, which makes it almost trivially easy to nest templates within templates, use different templates for different parts of the site, and to completely eliminate any redundancy in template code. Working with Django’s templating system is often described as “a joy.”
In contrast, a common complaint about Drupal is that templates can be difficult to customize. In fact, there are entire books about working with templates in Drupal.
Said one Django developer on working with Drupal templates: “I always felt like I was shoving a square peg in a round hole.”
Drupal developer “catch”:
Drupalâ€™s PHPTemplate theme layer gives you a lot of freedom to do processing in themes, which can be good or bad depending on situation/skillset etc. … However, even if you do have code which you need to share between themes: since at least Drupal 5, weâ€™ve had theme inheritance (sub themes) which means if you have some central logic which would need to be re-used between multiple themes â€“ whether thatâ€™s templates, CSS files, preprocessing etc. (either on the same site or completely different sites) then thereâ€™s zero need to copy this between them â€“ you just have your base theme with that stuff in, then build a subtheme on top of it, subthemes can be as light as a single CSS file.
The theme/sub-theme system does give Drupal the ability to do theme inheritance. However, the basic methodology still allows for the inclusion of business logic in themes, which breaks the separation of presentation, content, and programming logic. The Django project is very strict about this, and has been very good at saying “NO” to proposals to make Django’s templating language include more options for direct programming. The Django philosophy is, “If you feel like you need to do some programming in your templates, you’re doing it wrong.” However, it is possible to create your own custom template tags and filters to extend Django’s base template language. Developers often share these custom tags and filters on sites like djangosnippets.org.
Once you head down the slippery slope of scattering code logic between internal functions and external templates (which should be kept simple enough for a designer to work on), you lose the clean separation of logic and presentation and no longer have certainty that certain kinds of code must be in certain places. My view is that Django’s insistence on keeping as much programming out of templates as possible makes people better developers, since it enforces “best practices” in programming.
Contrast all of this to WordPress theme development, where developers have to copy chunks of logic over to the new theme manually if they ever decide to change themes.
In Django, development begins by defining the data models that describe the organization, publication, or site. For example, these might be Stories, Authors, and Presses, or Equipment, Schedules, and Reservations, or Faculty, Students, Courses and Evaluations, etc. All of these have datatypes and interdependent relationships.
From that data model, database tables are auto-generated, and the system becomes internally “aware” of data relationships. To query for various sets of data, the Django developer uses something called the Object Relational Mapper, or ORM. So, rather than writing raw SQL queries, the Django developer writes “querysets” like:
books = Book.objects.filter(author='Hacker')
In a simple example like that, there’s no real time savings over writing the equivalent SQL. But when queries become complex, SQL gets difficult and error-prone, while querysets remain straightforward and readable. When developers can save time and reduce errors, organizations save money.
Drupal does not have an ORM.
Preston Holmes: For relatively “flat” data, Drupal’s CCK is usable by non devs to create custom content types, and the Views module allow for simple generic_view style pages. When it comes to more complex objects, Django’s ORM is far superior.
Starting with the data modeling process is a key point. Django makes no assumptions about the needs of your organization or the shape of your data, which means the end product should fit your organization like a glove. Django projects are built up to fit the organization, whereas Drupal developers often talk about having to remove or work around the things they don’t need. Many developers who have spent time in both systems say the Django methodology is easier and faster.
I don’t have numbers to support this, and it would be quite hard to test without building the equivalent test site in both Django and Drupal, but the conventional understanding is that Drupal has a lot of functional “layers” through which all page requests must pass. This results in a high query count and relatively sluggish performance. Granted, this limitation is largely moot given that all high-traffic database-backed sites rely on caching to keep performance up, but it goes without saying that a system that’s as light on its feet as possible is desirable. A Drupal site is probably going to require caching to be enabled with a lower amount of traffic than an equivalent Django site.
Bruno Desthuilliers: I recently had to work on a not-so-complex (functionaly-wise) Drupal project, and the response times on my local station – all caches disabled of course – turned the development process into a sluggish nightmare. Never had this kind of problems with Django, even for far more complex apps.
Drupal is sometimes criticized for having a steep learning curve. But as someone who went through the Django learning curve last year, I won’t claim that Django’s is much better. This really depends on the pre-existing skills of the developer. In my case, my move from PHP-based systems to Django was my first exposure to object-oriented programming, my first exposure to Python, and my first exposure to MVC/MTV thinking. Not to mention learning the framework itself. I think we hear this complaint more about Drupal than about Django because there are more newbie developers in the Drupal world, while Django for the most part attracts more experienced developers.
In fact, I’d go as far as to say that Drupal has an advantage here for basic sites, where little to no customization is required. However, as soon as customization is required, you’re going to need an experienced developer on hand with either system. For systems flexible enough to let you build whatever you can imagine, there are no free lunches.
Be careful of the term “rapid application development.” Without good skills on-staff, there’s nothing rapid about working with either system. But with those skills, rapid application development is no myth. I can’t speak for Drupal here, but a few recent rapid-development case studies are interesting:
- michaelmoore.com, recently rebuilt in Django in five weeks.
- texastribune.org, built from the ground up in just four weeks with Django.
- Mahalo Answers, built in 35 days with Django.
- baynewsnetwork.org, an RSS mashup and aggregation site with a complex back-end that lets member sites have multiple members and single members contribute to multiple sites — built in 3-4 days with Django.
- django-treedata: Winner of the recent DataSF public dataset Hack-a-Thon, built in 8 hours with Django (and another 8 hours cleaning the public data set).
Both systems have fairly steep learning curves. But once developer skills are up to speed, it’s amazing how easy it is to get the platform to do most of the heavy lifting for you.
Note also that both systems are sometimes distributed as part of larger bundled packages (“distributions”) which extend their capabilities. For example Drupal is part of CivicSpace, which is aimed at building civic/community sites, while the Django world has the option of deploying the Pinax project, which bundles together dozens of re-usable apps to greatly reduce time spent integrating parts into a cohesive whole.
This is very hard to quantify. Both Django and Drupal let developers work with data models any way they please. The question is, what happens when you need to change those models, or add new ones? How easy is it to create new views or slices of the same data? What happens to the logic that ties your data together when the platform is upgraded?
Both systems value flexibility highly, though both go about things in very different ways. What I do know is that when visiting journalists tell us about their Drupal experiences, a complaint we hear a lot is “Everything was fine until we tried to change xyz — then everything fell apart and we’re still trying to recover.” Again, much of this comes down to whether you have good developers on staff more than it does to the platform. Still, the fact that Django is so intensely object-oriented gives it a leg up when it comes to moving things around.
That’s not to say that a complex Django site is infinitely flexible. Even well-designed data models have interdependencies, and a change made in one place can have real ramifications for other parts of the system, which may or may not be easy to recover from. Managers should not be given the impression that just because you’re using a “flexible system” and that “anything is possible” that the webmasters can turn the whole thing inside out on short notice. Things don’t work that way.
Drupal has developed a bit of a reputation for being difficult to upgrade, since so much changes internally between major releases. No platform is immune to that problem, but I’ve rarely seen Django apps affected by upgrades. And when they are, the fix is generally minor.
Bruno Desthuilliers: From my experience, it can take more time doing “simple customizations” with Drupal than you’d need to implement the same features from scratch in Python/Django.
A recent Django success story was the 4-week (!) launch of texastribune.org. Asked why the Tribune chose Django over other platforms, developer Chase Davis replied:
We went with Django for two reasons:
1. We decided early on that the Texas Tribune needed room to evolve. It’s a startup, and nobody has any idea what it’s going to look like in six months. That being the case, our goal was to build them a sandbox — something that could evolve as their organization evolved. We settled on Django because we thought a framework-based approach would give them maximum flexibility, while keeping the benefits of stability and rapid development. If they need a new feature — no matter what it is — we can prototype it, built it and integrate it quickly. We’re not limited by pre-existing modules or dependency issues you find with off-the-shelf systems.
2. The Tribune’s plan going forward is to integrate tremendous amounts of data into their coverage. Their lawmaker directory is one example of that, but they have much more ambitious plans for campaign finance records, financial disclosures, lobbying reports, etc. Rather than segregating that data by walling it off in its own ghetto, we thought Django offered the best chance to integrate it with other content on the site. Drupal isn’t great for building data apps; Django is. If we used Drupal for the CMS and tucked Django data apps within that, tightly integrating the two could quickly become a headache. But with everything in Django, our data apps and CMS play together seamlessly. You’ll see a lot more examples of that in the months ahead.
This is one area where Drupal really has the advantage. Don’t get me wrong – Django has a great community of developers who are more than ready to help each other out, respond to questions on IRC or mailing lists, and a really active blogosphere. But while there are many sites listing re-usable Django applications ready to become part of any project, Django simply does not have the immense collection of downloadable modules present in Drupal-land.
That doesn’t mean we haven’t been able to find ready-made solutions for most situations where we’ve needed them, but there are areas where we’ve really felt the pinch. Case in point: I recently had to implement a survey system on a Django site. That’s an important and not-uncommon piece of software, and you’d hope to find yourself choosing between lots of options. Unfortunately, I found exactly one re-usable survey app for Django, and it was somewhat buggy.
On the plus side, the developers of django-survey responded literally overnight to the half-dozen bug reports I filed on it the first day, but it would be nice if there were several mature survey apps to choose from. That’s the kind of thing that happens when community momentum really takes off. Django’s momentum is increasing by the day, it’s heading in that direction, but Drupal definitely wins in this arena.
Still, there are community-provided apps and resources I utilize on every Django project I build. And nothing in this department has ever been a show-stopper for me. Keep in mind that, in many cases, just building the re-usable app you need when an existing one isn’t available may be easier than expected.
Popularity / Installed Base
By some measures, particularly for decision makers, popularity counts. Is the platform popular enough that I know it’s not going to be abandoned? Can I readily find qualified developers? Is the platform proven in the marketplace? Drupal developer Zack Rosen has this to say:
- Drupal by all measures of an open-source project is a magnitude larger than Django. Core contributors, community members, deployed sites, any way you want to compare numbers Drupal is a much more established project.
- Drupal is more proven in the market place. It runs magnitudes more websites (500,000+), and many of note. Whitehouse.gov yes, but Viacom, Warner Brothers, Yahoo, Wikipedia and others all run highly trafficked Drupal sites and have made strategic business decisions to invest in the platform.
- Drupal has far better commercial support in the marketplace than Django. There are many more (and more qualified) Drupal development shops and specialized service providers in the marketplace.
Excellent points, which I would qualify by noting that Django’s popularity is rising, along with the number of qualified Django developers on the scene, and the number of high-profile Django sites appearing (just tonight, the Mozilla foundation announced that it would be moving its addons site from CakePHP to Django.)
After years of working with both custom and open source PHP code and applications, we felt that we had had our fill of PHP, which has a tendency to sprawl. Granted, sprawl is not much of an issue when working with pre-fab solutions like WordPress or Drupal, but Python’s syntax is clean and uncluttered, which speeds development time and encourages developers to think in more object-oriented ways. Simply put, clean code is easier to write and easier to maintain.
Mike Ramirez: Finally, there is the maturity of the language. PHP is still adding in features other, similar languages already have had. For example namespaces are just barely a year old in php, initial release in the dev versions, less than 6 months for the actual first appearance in a stable release. To quote wikipedia on missing features from PHP: “PHP currently does not have native support for Unicode or multibyte strings; Unicode support will be included in PHP 6 and will allow strings as well as class, method and function names to contain non-ASCII characters.” Seriously, in todays global world and well, for the past what 10-15 years, hasn’t this been mandatory? I do not understand why web developers who use php, still do. I don’t understand why companies and schools support it.
People often work in PHP because it’s the default, and easy to gravitate towards. But that doesn’t mean life couldn’t be a lot better with a cleaner language to work with.
Security is a multi-headed hydra, and affects all web applications, large or small. SQL injection, form sanitization, cross-site scripting, and many other attack vectors require web application developers to stay up to speed on current security trends and to examine old code for new vulnerabilities. It’s a constant chore.
One benefit of using a mature framework or CMS is that many of the most common security issues are handled by the system itself. This doesn’t mean we can afford to get lazy about it, but it’s good to know that hundreds of people smarter than oneself have pored over the code to identify and mitigate security issues.
That much is true of both systems. However, it’s also true that Drupal has a history of security issues, whereas similar issues in Django are extremely rare. This is in part due to the fact that Django has a lower public profile, and in part because Django makes fewer assumptions about where things live and how they’re configured. In other words, less about a site’s setup is known to a would-be attacker since sites built from a clean slate by various developers share less in common with one another.
There are other factors that may contribute to Django’s excellent security track record, such as its URL mapping system, which simply prevents access to URL patterns that haven’t been predetermined by the developer, and its exceptional form generation and handling system.
Still, I don’t want to emphasize the security point too much – all systems can be vulnerable if you do dumb things with them, and vice versa.
Drupal developer “catch” adds:
The Drupal security team regularly releases SAs for security issues which in some cases are theoretical, in many cases have never been exploited (simply reported after code review), and very often require either authenticated or some level of administrative access to a site. Additionally, the 3-4,000 contributed modules are hosted centrally on Drupal.org, not distributed around the web, and have the same rules for security announcements as Drupal core, handled by the same process. The number of security announcements for Drupal core itself is relatively low given code base and deployments.
On the other hand, PHP-based systems have a slight leg up in deployment. Since virtually every web host offers PHP hosting. In contrast, setting up a Django system on a server will take some level of fiddling that may not be familiar to the typical web developer. Fortunately, a growing number of web hosts specialize in Django hosting, which makes this problem go away in many use cases.
Preston Holmes: “Where Drupal has its single biggest advantage, is that a technical user, a sysadmin etc, can get Drupal up and running. Someone doesn’t have to know PHP AT ALL to get drupal going. This is because Drupal has a decent admin-UI – where modules are pretty much drop in, activate and configure. Setting up even a basic Django site REQUIRES someone who has some programming skills, even if thats just a matter of setting up the settings.py file.
But the Python/Django deployment hurdle is not huge, and is a one-time problem to solve. Once Apache has been configured to work with Django, you don’t need to think about it again. This hurdle affects hobbyists, who tend to look for a simple button in their web hosting control panel, far more than serious sites for whom server configuration is just part of doing business on the web.
I asked members of the django-users mailing list who had done development work with both Django and Drupal to provide comarison-oriented feedback for this article. Here are a few of their comments:
Preston Holmes: What happens is that non-developer/technical decision makers will evaluate Drupal and think that all their needs will be met out of the box. When they find out they aren’t, they need to hire developers, and then those developers have to massage existing modules to customize and tweak. Then at some point they have this monster of hodgepodge code. But its that entry point that is the key to Drupal’s popularity. … I don’t think people appreciate how much Drupal development is spawned by this existence of a usable entry point for Drupal by non- developers. (and that it has 1-click installs on hosts, and in general uses the far more common infrastructure of PHP-MySQL).
Javier Guerra: “Many people feel they have to code less to write their own Django-based CMS than to customize an existing one. If that’s your case, you’re a lot less likely to break something when going with Django.”
Clifford Ilkay: “On balance, I’d say Django is the more flexible and powerful of the two but Drupal gives the *illusion* of productivity quicker. With Django, I build up from a base, whereas with Drupal, I seem to spend an inordinate amount of time trying to figure out how to make it *not* do something I want done differently. Django is lean and simple by comparison to Drupal, which is neither lean nor simple. Both have very active and helpful communities. If I had the choice, I’d pick Django simply because I prefer Python to PHP and find Django to be more productive. Prototyping and debugging PHP is very crude by comparison to Python. Much of Drupal’s convoluted architecture and reliance on naming convention “magic” to provide quasi-inheritance is due to the limitations of PHP. I often say, half-seriously, that Drupal is good despite PHP, not because of it.”
Alexandru Nedelcu: Development in Django is a lot easier, because the modules are more generic and the development process is more predictable because of its simpler architecture.
Mike Ramirez: Django has made making web apps almost trivial and the most time I spend now, is on the UI (both Dojo and JQuery make this almost trivial also), rather than the back-end.
Preston Holmes: Both have the problem of often complex dependencies. The biggest problem with Drupal is its relatively fast moving core – so that modules for the “current version” are hard to find, or often abandoned. Also Drupal modules almost always seem to do 80% of what you need.
Milan Andric: Drupal might get you quickly to Point A, but the problem is in customization, pushing a site to do *exactly* what you want (nothing more or less) … My main problem with Drupal has been all the time spent removing stuff. The best tool for web developers right now is a framework, not a CMS. Regardless of the language it’s written in.
catch: Drupal 6â€™s API was officially frozen 2.5 years ago and Drupal 7 has been in rapid development for more than 18 months, with probably 1-3,000 patches committed by this point.
Preston Holmes: (On the ease of getting the system to do highly custom tasks): Django just wins this so hands down. Here is part of the reason why. Drupals assumptions translate into your code having to jump through a lot of hoops – where as in Django, you make the assumptions and you make the hoops.
Drupal represents a middle ground between framework and CMS that we’ve chosen not to take. Drupal is far more capable than a CMS like WordPress, but also much less flexible than a pure framework. But more importantly, the facts that Drupal isn’t object-oriented, isn’t MVC/MTV, doesn’t have an ORM, and is generally less flexible than a pure framework, not to mention our preference for working in Python over PHP, all contribute to our decision not to use it.
In the end, a good developer can do good work with just about any system, while a bad developer can make mincemeat of even the best system. It’s not all about the platform. But modern tools and best practices in platform design go a long way toward ending up with a cleaner, faster, better-designed architecture that precisely matches the needs of your organizations, with no assumptions or historical baggage to work around.
Note: Public comments below may be incorporated into the document above. Thanks for your feedback.
Update: This post sparked an interesting thread on the WordPress Hackers mailing list.
Update: Drupal developer Nick Sergeant has posted a similar piece: Drupal v. Django