As any regular reader of this site knows, I’m an avid user, fan, and evangelist of Django, the popular web application development framework written in Python. I first got into Django about two and a half years ago, when I joined the team at (what was then called) World Online, the interactive division of a Lawrence, KS news media company. After several months of learning the framework and building a few simple sites with it, I wrote a blog post entitled Top ten things that suck about Django. The title of the post was chosen with tongue planted firmly in cheek, as a response to some folks complaining about me being an “annoying fanboy” with my Django evangelism. I wanted to show that despite my affinity for the framework, I was more than capable of seeing Django’s flaws.
That post was written almost exactly two years ago. It’s now been about three years since Django was open-sourced (Django was born in the fall of 2003 and released as a public open source project in the of summer of 2005). With Django 1.0 finally being slated for release in September of this year, and a feature-complete alpha version already available, I thought it would be an interesting time to revisit my list of “things that suck” and see how Django has evolved. While I’m at it, I’ll take a look at some of the things that commenters on the original post thought sucked, as well.
When I wrote the list, I was unable to actually come up with ten items to fill it. So, I listed six. Unfortunately, the short story is that most my “things that suck” have not been addressed, two years later. Let’s take a look:
- Painful schema migration. Back in 2006, I noted that schema migration is a complicated, annoying process in Django, and usually requires writing SQL. Unfortunately, the same is still true. When I wrote the “things that suck” post, I said, “Good news is, there are at least a few in-progress attempts are correcting this, including a Google Summer of Code project.” Curiously, I have no idea what happened to these. If they were ever finished, I never heard much about them, and they certainly never got rolled into Django itself. Schema migration continues to be one of, if not the, biggest annoyance in Django development.
- Admin interface/authentication module: inability for a user to edit only objects he/she has created. This problem has been addressed with the merge of the newforms-admin branch. It’s not as simple as I’d like, but allowing a user to edit only items he/she created is at least possible, now.
- Admin interface: inability to delete multiple items at once. This problem still exists, and it still a pain in my ass virtually every day.
- Contrib apps: No django.contrib.search. As I said in the original post, “the contrib apps that are bundled with Django basically try to cover common cases for you, making the things you do over and over again easier and faster. Some of them include a feed creation framework, a generic comments application, the admin interface, the auth/auth module, and more.” To date, no one has seen fit to add a generic search engine to the mix, despite the fact that almost every site in the world has a search box. This is baffling to me. In talking to some friends from Lawrence about it, I have come to two conclusions: first, search is complicated. Second, search is complicated mostly because of features 90% of web sites don’t need. Every time someone talks about django.contrib.search, they start going on about indexing, relevancy, scaling, and so forth. While I recognize that all of these are important issues to be solved, I still don’t understand why Django can’t bundle a simple SQL search engine that would cover the needs of most everyone not named The Washington Post.
- Install: Relatively painful process. I’ve never used Rails, Cake, or any of the other popular web app frameworks that Django competes with, so I’m not able to make a good comparison between Django’s install process and any others. Maybe they’re all pretty tricky. What I do know is that Django still feels like it requires a lot of steps to install, and the install process hasn’t really changed since I wrote the original piece.
- General: The fact that the trunk branch and release version are so different. This problem has been solved. At the time I wrote the piece, Django’s trunk had been merged with the magic-removal branch, but the release version had not. The documentation wasn’t clear as to which you should be using. Today, the two version are much more in sync, and the documentation is very clear.
As you can see, many of the things that I considered to be amongst the most sucky things about Django in 2006 are still issues. But, is it possible I didn’t actually know what sucked most about Django? I would say yes. At the time I wrote the piece, I didn’t understand the deeper problems Django was dealing with, such as an unsatisfactory forms package, lack of proper Unicode support, some definite shortcomings with the ORM, and the fact that admin options were so closely tied to Django models. All of these major issues have been addressed in the new Django 1.0 alpha. So, that’s terrific.
When I wrote the original piece, several commenters chimed in with their opinions about sucky Django bits. Here are some of their thoughts:
Here’s a #7: lack of an end-user testing framework. Tests are really important to application quality, and Django needs a way of doing them that lives up to the slickness of the rest of the framework. — Jacob Kaplan-Moss, Django lead developer
As Jacob pointed out, the lack of a proper testing suite was definitely a major problem, and I’m happy to report that it’s been fully addressed. Django now includes a great testing framework.
It doesn’t come with a pony. — James Bennett, Django release manager
Sadly, Django still does not come with a pony.
Seriously, though, I’d really like to see some refactoring in django.contrib.comments to make it easier to extend without hacking the source. — James Bennett, Django release manager
This is something I’d like to see, too, and it still hasn’t happened. I’m not sure what the status is. Anyone? Jacob?
I’d love to have something better than get_absolute_url. — James Bennett, Django release manager
Django definitely has improved its URL configuration by adding named URLs, which allows for URLs to be configured in only one place, rather than two, as was previously required.
Where is the easy ajax support? — “Jake”
Django still offers no built-in “AJAX support,” and quite frankly, I think this is a feature, not a bug. I’ll chalk Jake’s comment up to it being 2006, when everyone was creaming their pants at any mention of “AJAX.” Django did, however, add serialization of objects to XML or JSON, a feature which definitely makes doing AJAX-style development easier.
I think the thing that sucks about Django most is that Jeff won’t shut up about it. :-) — James Asher
This problem has been largely solved. I stopped talking about Django much on this blog after it was clear I was annoying folks by supposedly “fanboying” the framework. In fact, this is my first Django-related blog entry in well over a year.
Can’t edit passwords directly for users in the admin. — Rob Hudson
This has been solved! You can now edit a user’s password in the admin in a secure way that doesn’t display the password to the editing superuser.
Bill deHora offered a long list of his own:
1: model inheritance 2: inconsistent unicode 3: admin app doesn’t have a model builder 4: committers aren’t scaling to issues/community 5: surprisingly awkward to find an angle into commiting patches (maybe that’s just me, but it’s hard to know what the committers actually want to focus on sometimes). I seem to be talking myself into the unicode bit 6: no deployment tools (I’m with Vogels - you build it, you run it) 7: contrib.search - check. Tho’ i don’t see this being any less contentious than the current tourniquet fest over js libraries. It’s got to be a callout to lucene via the A9 api, right? 8: having to explain to people Django is production ready now; please land a new rev 9: too much talk about js (go Bennett); it’s an energy sink 10: no tee shirts. 11: “there’s a google summer of code project for that”
Quickly: 1. Solved. 2. Solved. 3. Not solved. 4. I’m not sure. Anyone? 5. I’m also not sure. Anyone? 6. I think this is improved, but it still may be a bit of an issue. 7. Unsolved, as previously mentioned. 8. This is definitely still a big problem. I hope 1.0 fixes it. 9. This seems to be a non-issue these days. 10. Solved! We have tee shirts! 11. This is still a major problem. :)
Conclusion
Overall, I think Django has made incredible progress over the past two years — if not on the items I thought I wanted it to. However, I now realize there were far more important issues at hand, and the Django community has addressed a ton of them. Django is a much, much better framework than it was two years ago — and quite frankly, if the community had focused on my complaints rather than the things it did, it probably wouldn’t have seen so much improvement. So, kudos to everyone involved in getting Django to the 1.0 alpha. Really awesome work. I continue to use and love Django every day, and I honestly don’t know where my career would be without it. It’s been one of the best things to ever walk into my life, no doubt.
Still, four of my six items remain annoyances and quirks that bother me on a near-daily basis, and I’d love to see them get some attention as soon as possible. :)
Discuss.
Well, on the deployment front, I’ve been trying to dig into Capistrano lately and see how that works for Django deployment. It’s certainly not something it was built to do, but I think it could ease the pain if people would share their Capistrano recipes.
Not specifically about Django, but about it’s community—whenever I check into #django, it seems like there are one or two very knowledgeable, but very rude, people polluting the air. I don’t know who’s in charge of that room, but I’m afraid that kind of thing could tarnish the community’s reputation. It’s generally very helpful, don’t get me wrong, I just tire quickly of flippant “RTFM” type comments.
So where can you get T-shirts?
Schema evolution and difficulty in extending contrib.comments continue to be two of my greatest problems with Django. With that said, I think #2 on your list has gotten better thanks to newforms-admin.
I haven’t tried this yet myself, but couldn’t a custom permission (as shown at NewformsHOWTO) solve this problem to prevent a “Change” page being shown for any user that did not create the object?
For the list page, could the ModelAdmin queryset method be overwritten to only return that user’s items, unless the user is an admin?
I don’t yet have a project moved to nfa to test this on, but it looks like this could work, even if it isn’t the easiest method possible.
@Trey: I don’t think t-shirts are for sale anywhere at the moment, but they’re usually being passed out by community leaders at conferences and such. The t-shirt situation is one that can always be improved. :)
@Ryan: Absolutely. NFA did make it possible to do what I was referring to in #2. You may not have seen the updated post, but I was informed I was wrong about #2, and I fixed it. :)
Ah, cool. And I thought I was being clever…
Did I at least have the methodology right? Or is there a more official way to do this?
@Trey Piepmeier I think one year ago I also wrote a blog post about Django, Rails and some other frameworks (from the view of a new guy trying to find the right framework) and said that Rails seems to have a more friendly community (IRC) than Django.
I think this changed.
I asked some questions the last few months and also read a bit what other people are asking / answering. The people were great. Nearly all questions were answered. Point. That’s the most important thing.
Pointing out to read the documentation is IMHO valid. You don’t always know that it is documented or you don’t find it while looking. And IMHO it is natural that someone got a bad day and is not as friendly as he could be - that’s also okay as long as he is helpful.
@Timo Zimmermann - I totally agree that being rude and helpful is a lot better than nothing. And I also agree that it’s best to read documentation—but a little tact and benefit-of-the-doubt attitude goes a long way.
Good post, Jeff.
In regards to Schema Evolution,
django-evolutionis a surprisingly mature and full-featured schema evolution project that I’m sure will be included in django.core some day:http://code.google.com/p/django-…
You can still run into some weird edge cases, especially if you’re using custom model fields, but for 90% of common cases, it works beautifully.
Installation of Django might only come across as tricky because people end up just following a list of commands from a website rather than understanding the steps. The fact that there are so many tutorials might actually make it more difficult to find the definitive one that explains things well.
On a unix box installation of Django is basically 3 steps:
That is basically all there is too it. I imagine there could easily be installers that take the role of the 3 steps and starting your first app but even doing it by hand is fairly straightforward even for those who’ve never touched the terminal (I have seen terminal newbs no issues up until they try to install mysqldb on leopard).
Getting Django running with a web server is more tricky, but ultimately of equivalent difficulty to anything that isn’t executed directly by apache (or equivalent).
My main problem is there are now about a billion downloadable apps that start with django- creating some bizarre new version of the php namespace hell but with applications instead.
I also think the method for writing template tags and filters could do with being tidied up since there’s a lot of stuff that could be abstracted away into a very elegant interface. Writing a template additions isn’t difficult but it is my least favourite part of using Django.
Now that newforms-admin has landed I’m hoping for a lot of functionality enhancements for the admin post-1.0 since there’s a lot of functionality that I would consider quite common that it simply doesn’t have. If i’m building something quickly to the point where I don’t have the time to write my own admin views I find myself restricting the architecture of my models based on what I know can be reasonably usable through the admin. So the more the admin tool can take care of common use cases the better.
Nice post Jeff. Really good to see a post about Django from you. I don’t care what others are saying, it’s been too long. Keep it up!
You’re right. It’s not really that tricky, and now that I’ve done it a hundred times, I can pretty much do it in my sleep. But it’s still a user’s first impression of the framework, and I think there’s room for improvement.
Deleting multiple objects in the admin was a huge pain in the ass for us too. It’s possible to hack the admin to get this functionality; ugly, but it works.
There should seriously be a contrib.search app that functions much the same way as the Admin’s ‘search_fields’ does. How fantastic would it be to simply register models as Searchable by providing a list of fields on which to search? Pretty damn fantastic, you better believe.
@Trey: Regarding deployment, there’s now a Python tool similar to Capistrano, Fabric: http://www.nongnu.org/fab/. It’s still in its infancy but has a lot of promise, especially since — being newer and smaller — it can go in different directions, architecture/feature-wise, than Capistrano has/can.
I’m sort of biased since I’ve been hacking on it lately (yay for Git) but just wanted to throw it out there. Capistrano is obviously still an excellent choice, having a bit more mindshare and features at the moment.
I agree with most of your points, and see why they weren’t the things that the Django core team wanted to deal with initially.
Jeff,
Nice to see you posting about django again.. we like your “fanboy” status :P
i remember reading your original post when i first started playing with django. The real deal breaker for me then was the admin system and its implicit trusting attitude. newforms-admin seems to have fixed this.. and i’m dying to have a poke at it and see whether the admin is ready for deployment for a client. For me (and i’d say others would agree).. the django admin being so feature packed is one of django’s most appealing features..
Thanks for the thoughts, Jeff; a lot of good stuff to think about here and in the comments. I think your general take-away is correct: we’ve needed some time to clean up Django’s internals so that we’re left with a stable platform to build off.
Good news is that I’m extremely happy with where we are now, and pretty confidant that 1.0 will be that platform. So hopefully we can start tackling some of these pain points. In most cases it’ll actually be pretty easy: things like django-evolution and djangosearch are getting to the point where we could start thinking about bundling into django.contrib; that’ll be awesome.
I’m particularly interested in your thoughts on the install process — what do you think we could do to make it easier? I think having a stable 1.0 out will help a little bit (by taking away the “which version?” question), but I’m not quite sure what else we could be doing. I’m sure you’ve got some ideas — wanna share?
On the
contrib.commentimprovements front, see:Also, the pony thing has been resolved over at dpaste, although still not included in
trunkunfortunately.I’m not sure how much about install can be improved. Or rather, I’m not sure the actual process can be improved. The end user experience can be improved as more hosts pick up Django.
WebFaction, and soon, MediaTemple hopefully, make Django installs much easier by taking out the installation.
This may be why a PHP site appears to be easier to set up — that’s because a majority of hosts have already handled the other stuff (setting up the Apache modules, tuning any PHP acceleration, etc.). In reality, setting up a Django install is only a few more simple steps after that; steps that a host can easily do as part of the automated setup procedure.
Django will likely never be as brain-dead easy as PHP due to the nature of the long-living memory model, but it can be just as painless with proper host support.
scheme migration works, albeit as a third-party app. google deseb.
I agree with you on the whole, but I think you forgot about some points. We have developed a bigger application (with forum, wiki, blog, planet, portal) currently in productive use on a heavy loaded site and we are trying to kick django since the start of the project.
Django is create for small CRUD applications (and there, it isn’t that bad), but it’s not usable for bigger things. The main problems we encountered are:
But i think that’s only a small subset of all the things which makes Django so unusable for such projects. Maybe you can name more? ;)
On installation: Frameworks don’t need an installer. Instead they need to make themselves easily included in an installation tool. You don’t just install Django - you install a project that happens to be written in Django. Installing that project should include installing Django as part of the install process. For new Django projects, this would mean another small tool that makes it easy to get started with a barebones installer.
This is what we do in Grok (and it rocks IMNSHO). We use zc.buildout as the install tool - and another small app called “grokproject” to make it easy to get started on a new Grok application. A new users experience installing Grok is then:
This works wonderfully for any application which makes use of a modest amount of additional Python packages. If someone has made a Grok application that makes use of say, 5 additional Python packages, I can checkout their code from svn, then do:
From here I can start-up a fully functioning application with everything included - the specific versions of those 5 additional Python packages required, database server, web server, ldap server, kitchen sink, etc. An uninstall is just “rm -rf somegrokproject” and doesn’t require any futzing around in site-packages or any places outside of the project directory.
Also, a good install tool makes it easy to upgrade/downgrade individual parts of the framework or related packages. For example, say I am using (a theoritical) Django 1.1 and I want to just upgrade the django.comments app. I could edit the install config file and write something like:
Re-run the installer (./bin/buildout) and just have the comments app updated. Then I see on PyPI (or elsewhere) that dj.supercaptcha is available. This requires django.comments > 1.3. I want to use this so I edit the app package specs to look like so:
Then I can remove the “django.comments = 1.2” line that was pinning me to that version of that app, and the installer will be smart enough to realize that dj.supercaptche needs djanog.comments 1.3, and it automatically pulls in that newer version in the app install. If a django.comments 1.3.1 bug-fix release is made, I can just re-run the installer and it will fetch and install that version.
Christoph Hack,
also, most of your comments are very very subjective and lack any concrete juicy details (ie the “templating engine they use is extremely slow”, “the url building just sucks”, “you need to use raw queries even everywhere, to get that what you want”,”you can’t change some millions of entries at once, because of limitations of the orm “ etc.)
and i am sure you are aware of these posts, right? http://lethain.com/tags/django/
basically you can swap the orm or the templating engine
personally i think the only valid comment you had was about the admin-dropdown which was already mentioned by Jeff by the way.
by the way this also sounds very trollish (and subjective), could you please be more constructive?
if you wanna see what has been built with django, please see http://www.djangosites.org/
Try either web.py or cherry.py
Did you even read the article? I love Django. I wouldn’t consider using another framework.
Glad to see another Django post from you. It’s been too long, and is what drew me to your weblog in the first place. Please keep it up, as you add valuable insight into Django development!
@Jacob
I think a Django Gem would be great. Even though that’s a very ruby-centrict thing to do, certainly the install process could be written in ruby. Or maybe we need a Python Gems.
To give you an idea on the difference. To install rails on OS X, you need to have the Xcode tools installed, open terminal and type “sudo gem install rails —include-dependencies” and there you go. Installing Django is much more complicated.
Being pretty new to Django, the only thing on this list and actually the only thing in Django that I’ve been a bit bummed about is the lack of bulk delete in the admin - which I feel is a bit overdue.
As for the install process, the first time you do it you’ve got no idea what or why you’re doing the different steps - especially coming from a background using PHP on a shared hosting. But as you mess around on various linux boxes and get comfortable I personally feel that with apt-get and install.py it’s quite easy and quick.
Though I wish there was a bit more documentation with running Django on lighttpd & fastcgi. There’s a lot of tiny things that turn out to be different from running an app on mod_python with apache (such as
APPEND_SLASHdisappearing and admin redirecting to /django.fcgi/admin/ rather than /admin/).Kenny, you mean something like “easy_install django”? There don’t seem to be any packages set up at the moment for Django but we wouldn’t have to reinvent gem since an equivalent already exists.
Interesting post… I liked how you also responded to the comments of the previous post as well as what you wrote.
Aside from the things mentioned in your post and the comments of others, I’d say one thing that Django lacks is an authoritative registry of pluggable apps, preferably hosted on the djangoproject.com domain (apps.djangoproject.com?). An authoritative registry would allow one-stop shopping for downloading and rating Django pluggable applications. As it stands there are at least three non-authoritative app directories, Google code itself, and a wiki page linking to various projects.
Earlier in the year I did a talk (PDF) on the state of unofficial Django pluggable apps and arrived at the conclusion that a lot of work needs to be done to improve the ease of setup for a lot of these. The Pinax project seems exciting in this regard: they’re creating a suite of Django pluggables that can be used either separately or together to provide an out-of-the-box site providing high-level social networking features.
@Andrew
Being unfamiliar with the Django community, and commenting only on the install process listed on the main site, I believe that easy_install (after googling) would be a great alternative.
There is also the matter of getting python to play nice with mySQL, which is a giant pain. Why doesn’t Django have that built in, why the fuck am I compiling it? Doesn’t make sense to me for something that’s supposed to ease development that perhaps we could take out the process of hooking into mySQL and automate that?
I don’t really understand the concept of symlinks either. Why can’t I just get in and start programming right away? Isn’t that the point of frameworks. The install isn’t awful, it just feels counterintuitive. I was able to get rocking with Sproutcore, Rails & CodeIgniter in much less time.
It’s possible, if you mean getting a URL out of parameters. Template tag ‘url’.
Simply not true. You just threw that out there, didn’t you? Besides, nobody forced you to use Django’s templates. Jinja templates and Django templates look almost exactly alike, changing should be a breeze.
And yes, Django does have issues when the projects grow large, but more so because you start solving things the wrong way. (Putting form HTML in the templates, repeating code, misplacing view code into model methods, …)
Although I generally agree that when I’ve had to compile Python/MySQL support it’s been a pain in the ass (I’ve never had to do this on a web host’s setup, though — only on my local Mac), I’m not sure this is Django’s problem to solve. Also, I wouldn’t ever want Django to assume people are going to be using MySQL; Django shouldn’t have any database preference.
Which symlinks do you mean? There is no symlinking involved in the Django install process. For reference, here’s the instructions from the How to Install Django page:
It really is fairly simple. I think the trouble for most new Djangonauts is not really installing Django itself, but getting their environment set up for it — configuring their database and Python support for it, setting up their Python environment variables, (sometimes) installing Python itself, etc. As much as I think the process of installing Django is sort of a pain in the ass and daunting to newbies, I’m also not sure it’s really Django’s fault, and I’m not sure how Django could solve it.
@Jeff
“I’m not sure this is Django’s problem to solve.”
Well, it’s not something that Django, as a framework, should solve, but it is something that can and should be improved within the Django ecosystem. Having a good build process in place is an important part of any project! Developers should not have to use sudo and install things as root. Developers should not have to track down any Python libraries that a project depends upon and install them one-by-one by hand.
A Django project installer could prompt you for which database you are using, and write out the appropriate build config, then run that initial build. This should then give you an isolated Django install specific to that Django project, w/ correct database and python-database libraries. Even better, you can trivially reproduce that specific development environment on another developer’s computer. This is work that the hosting providers could benefit from - if you’ve got shared hosting w/ Django and are using specific web config and database versions, then if you can make it easier to reproduce the exact production environment in development, alls the better.
Python has a wealth of build tools, it’s just a matter of enough Django people learning and adopting these tools and sharing their knowledge and recipes of them. We have already solved this problem in other Python frameworks, Django just needs to play catch-up for a bit!
Agreed.
Agreed. But, do you actually have to track down Python libraries to install Django? I’ve never had to.
Well, you wouldn’t want to do this in the Django installation process. Choosing a database should be done while setting up an individual Django project, not Django itself (because you regularly want to use different databases for different projects).
But, a Django installer that prompted you for which databases you want to install support for, that downloads, installs, and configures any necessary libraries automatically, would be brilliant. Not sure how feasible it is, with licensing and all — but it would definitely be nice.
Ohh, I see where you’re going with this. I guess I can see the value in that for some circumstances, but I personally much prefer having one global Django install, rather than a Django install for every project. Somehow that feels inelegant to me.
This stuff is largely over my head. I’m not a very good person to ask how the install process could be improved, because I don’t very well understand the processes, tools, and technologies involved.
But, what I do understand is this: a lot of people are coming to Python specifically to use Django. That means a lot of people are trying to install Django that don’t already have a Python development environment in place. Django’s three-step install process is pretty simple for people who understand how Python works and already have database connectivity configured. However, for someone who has never used Python before, getting Django running can definitely be a frustrating first impression. You can I understand that a lot of that frustration isn’t really Django’s fault, but a newbie probably doesn’t see it that way. Installation is a user’s first impression, and the smoother it can be, the better.
I see it as marketing thing, more than anything else. I think there is some hesitation amongst the upper echelons of the Django world to concern themselves with marketing of the framework. There always has been, and I think that’s a little sad. But, Adrian has also always said that at 1.0, Django would launch some kind of killer marketing campaign designed to draw droves to the framework. If that’s still the plan, I think a simple, sexy, appealing install process could go a long way towards reaching that goal.
There is a use of symlinks from the Trunk and a more manual install. Setup.py is great, and I’ve used it successfully. I was referring to @Andrew’s install process.
I agree that Django should be Database agnostic… and by database agnostic I mean build into their setup process the ability to easily hook into at least the top 10 most popular databases and then allow other or future dbs to add later.
cough like Rails cough :)
I’ve found that setting your pythonpath and path or using symbolic links gives you a more useful environment than just running setup.py.
Running setup.py copies the library into site-packages (or at least it did last time I tried), I prefer keeping my downloaded libraries somewhere else, hence the symbolic linking. The reason for doing this is that it keeps the svn information in the same django folder that all my projects are referencing so all I have to do is svn update to upgrade all my sites to the latest version.
No. But to install a project which uses Django you can. A typical project built with Django might require: your own project-specific code base(s), PostgreSQL > 8.1, psycopg2, satchmo = 0.7, Pygments = 0.10.
Some people are doing this already - here is a recent write-up on repeatable Django installations.
Well, this is just my opinion, but frameworks don’t need installers. They need to make themselves more friendly to be included with assorted install processes and tools. For example, I think that the recently added Gem Dependency tracking feature in Rails 2.1 goes about things bass-ackwards. Rails shouldn’t be selecting the packages, the project’s build/install tool should. If you’ve got a nice selection of Gems in Rails 2.1, how can you re-use that same working set of packages outside Rails?
It’s possible to share common install parts between different project installs. But installing w/ shared or non-shared is a user selectable preference. Typically in a development install I share parts, in a production install I may choose not to. However, each project should maintain it’s own specification of required parts. e.g. ProjectA might be pinned to Django 0.96, ProjectB requires 1.0alpha, and ProjectC is developed against trunk. You often have a “dev” build and “production” build or some easy way of toggling between a released version of project and a subversion checkout. Dev builds can also be helpful by installing dev-support tools specific to a project. One project may install PyLint, another project might install PyChecker - but both projects only install these parts specific to the project’s development build.
Globally shared Python development environments are the easiest to get started with, but they can become a beast over time as more and more stuff gets stuffed into them. Especially when working on lots of projects - if you are in a consulting context for example, and one client says, “we are running production on RHEL4 w/ PostgreSQL 7.4 and Python 2.3” and another says, “we are running production on Debian sid w/ PostgreSQL 8.3 and Python 2.5” then it’s very nice to be able to easily separate out the install requirements between those two projects.
Agreed. If a newbie gets stuck on database drivers, they might give Rails a try and not encounter the same problem, and then make unfair statements such as “Rails is easier to install thank Django”. But I think it’s important to educate newbie developer’s to think in terms of project-based installs. If they have a Django project which is a PITA to install, then they shouldn’t think of that as something which is Django’s fault, and instead approach it as fixable in how they choose to manage their project.
There is a marketing decision in there - global development installs are more understandable to a newbie. There is more of learning curve to explain, “you are creating a project installer which installs the framework” than “install Django globally”. But global install can bite you, and unfair or not people are going to blame the framework. Ultimately though, having a newbie Django install experience be, “run a newproject app, answer some starter questions, generate then run a starter project build config” can provide the best of both worlds. Newbie get up and running quickly, and they don’t have an install process which they need to grow out of re-learn different deployment techniques later down the road.
But then from a marketing perspective, I’m not a Django-ite, so my only marketing message is concerns with comments like Kenny Meyers, “Or maybe we need a Python Gems.” Well, we do have Python Eggs, and Python’s web ecosystem is large and vibrant, so just ‘coz it’s not part of Django doesn’t mean it doesn’t exist.
However, I see install largely as a developer thing. If you’ve got a cool open source web app, I’d like to be able to easily install it, use it, learn it and hack on it!
This is already the case. Django allows for pluggable database backends, of which there are several included with the Django distribution (MySQL, Postgres, Oracle, SQLite), and more in development.
Just like Rails.
I have, too. Unfortunately, this process isn’t very well documented for newbies.
You’re sort of making this assumption that everyone who wants to use Django wants to install an existing project. I don’t think that’s the case. Rather, I think the vast majority of people who want to use Django want to use it to create their own projects, not install third-party ones.
I agree with this. There’s definitely a problem with people new to Django not really understanding that Django is just a small piece on the overall Python ecosystem. But, how to solve that? I have no idea.
@jeff
Fine, then Python needs to have its mySQL connector built-in among others
cough just like Ruby cough
Ruby has MySQL connectors built-in? I’ve never used Ruby, so I definitely don’t know for sure, but that seems odd. If they’re built in, then what is this?
http://dev.mysql.com/downloads/r…
I think I just didn’t explain myself well enough. Maybe instead of saying “frameworks don’t need installers” I should say, “frameworks shouldn’t be tightly coupled to the install process”. For starting on a new project, this means that a “Django installer” would create a project’s starting build config file(s) (from a template) and run them. As far as the new user is concerned, they’ve “installed Django”, only later on when they ask, “how does another developer install my Django project?” do they need to be aware of the distinction between “installing Django” and “installing a project which depends on Django”.
@Kenny
No, Ruby doesn’t have it’s MySQL connector built-in - otherwise Rails wouldn’t have made SQLite3 the default database. And running “rails -d mysql myapp” to switch from SQLite3 to MySQL is an example of tightly coupling a framework to an install process.
Kevin: Thanks for clarifying. I think I understand what you’re getting at, now. :)
@Jeff
Do you see that part where it says “(This module is also included in the Ruby on Rails distribution.)”
I’ll admit I was wrong about the Ruby MySQL connector, but really I was just taking pot-shots at Jeff because it’s fun.
I do know to hook into your mySQL database all it takes is mySQL and “rails -d mysql myapp” as @Kevin pointed out. I don’t think, however, that coupling a framework to it install process is a problem. I think it’s a necessity.
Please no Gems for Django. I like Python modules as they are. I can put them wherever I like them, symlink them, include them in my modules. Gems are a pain.
It’s not that easy when you’re behind a proxy … And I am.
Here are the things that annoy me the most about Django.
Actually since all my requests here involve databases, maybe moving the database settings out of the settings.py and create a database.py file which can contain multiple database settings. For each defined database, you could specify how to communicate with it, i.e. what ORM to use, and define what type of primary key to generate, auto-incrementing integer or UUID, or a custom key.
I’ve heard several of the Django lead developers mention this one, so I know it’s in the works for a future release.
From what I’ve heard, I’m doubtful SQL Alchemy will ever be the default ORM for Django. However, you should definitely be able to choose it instead of Django’s ORM if you prefer. I think you can do that now. Am I wrong?
Good to know that the developers are thinking about allowing multiple database configurations.
I know Michael Trier has been working on a project called Django-SQLAlchemy. You can get it here: http://gitorious.org/projects/dj…
I believe you cannot use SQL Alchemy with the Admin stuff.
Well, it makes sense that each app would have to be written for one particular ORM, unless you did something gross like a meta syntax. I guess I understand the desire to have Django work well with SQL Alchemy, as it clearly is more robust, but in real-world use, I have never come across a situation I couldn’t easily handle with Django’s built-in ORM. I fully admit that my applications tend to be simplistic, though.
It’s not something I personally would ever call a priority, but I know there are people out there that want it.
@Jeff
It is completely possible to use SqlAlchemy within django. In fact, we are doing just that. There are some drawbacks, but there are advantages. For instance, most of the contrib parts don’t work. But, there is the added benefit of composite primary keys, true join tables, support for more db backends and multiple database support.
Thanks, Matt, for clearing that up! Glad to hear it works well for you. Like I said, I find the built-in Django ORM to be more than sufficient for my needs, but it’s awesome to know you can swap out to something more complex if it’s needed.
for problem2 i use this solution
A little simplifies for remove items (problem3):
http://webnewage.org/post/2008/1…
@Slavonic:
Yeah, that solution works well with newforms-admin. I just wish there was a way to to do that globally on all models without having to explicitly define it in an Admin class for each one. Something like, “for all models, only let non-superusers view and edit items they created.” The trouble, of course, is that Django doesn’t currently keep track of what users created what objects.
Another “thing that sucks” to throw out there: no pagination in date-based generic views. However, I talked to Jacob Kaplan-Moss and some other Django folks and it seems like there’s a general consensus that there should be pagination in these views, so hopefully it’ll get added in the reasonably near future.
I agree heavily with 1. It’s my major problem.
Also another thing I’d like to ask is the possibility of read-only details in the admin. I want to give users permission to see a table, but not change it.
contrib.search would also rock my world.
People who think you can’t do multiple databases in Django are… well, wrong.
You can do it right now if you’re willing to write a bit of code (simplest case: a manager class) to get there. You can also do sharding. You can also do connection pooling.
Just because something’s not configured through built-in options in the settings.py file doesn’t mean it’s not possible. And if somebody wanted to go wrap all of it up in a nice couple of settings, well, patches are welcome.
And don’t even get me started on the query stuff the ORM can do these days, all while people sit around patting themselves on the back for knowing that it can’t.
Great post, Jeff. If I could have just one thing on your list, it would be django.contrib.search. I’ve been waiting for that for a long time, and getting django-sphinx or something working reliably seems more daunting than getting django itself running. That’s not a knock on django-sphinx, either.
I’m a member of those unwashed masses flocking to Django from PHP, and I’ve found myself vacillating between loving and hating it. A typical part-time PHP person with no CS background is getting hit with a LOT all at once:
I’m taking an O-O Python class, reading Django docs, and building Django sample apps as fast as I can, but what’s tripped me up the most is the fact that:
1) I often can’t find what I’m looking for in the docs because I don’t know what it’s called in Django. For example, it took forever to find out that I could send global variables/objects to my templates with “context processors.” There are docs, but searching on “global variables” will never get you there. The docs really need some kind of tagging system to help parse real answers/solutions out of the soup.
2) Once I do find the right docs, I often find them inscrutable, using a lot of terminology I’m not familiar with, not telling me which files to put things in, not providing enough sample code. Maybe it would annoy more experienced developers, but I’d be progressing much more quickly if every documented item came with full excerpts from a working model and a working view. There’s some of this, but not enough, and I often find it difficult to get the code samples in the docs to actually work in my own apps.
3) Documentation for some 3rd-party apps is even worse. Many of you might find the docs for django-profiles sufficient, but it took me many hours to get things working due to lack of working code samples. Coming from the PHP world where you grab a plugin or module for some CMS and things “just work,” going through this pain makes me question the “rapid application development” promise. Right now, I feel like it’s going to be a very long road to learn enough about Django that I can build a site with it faster than I can with my toolbelt full of PHP apps.
I love Django in principle, but the Django world just isn’t newbie-friendly enough to make it easy or particularly pleasant. If I didn’t have a work environment that was supportive of me putting in dozens of hours into pure training, it would never happen.
Scot, I think you make some very good and valid criticisms. I agree on all points, particularly the one about terminology.
I feel compelled to add that django now has a pony, thanks to Bryan Veloso. Http://twitter.com/djangopony
UUID as primary key
Look here for a Django implementation:
http://www.ibm.com/developerwork…
Please review the issue with the pony: it seems to have landed: djangopony.com
Beware: the glitters do not come off easily!
Thanks for the insights Jeff. Our little company has been working with the Zend Framework for the past year and as we look to new bigger projects we’re actively considering Django so it’s very helpful to see an honest list of downsides to the framework presented by an experienced developer.
One minor point - it’s been a while since I’ve actually checked out your site as I usually read via RSS but I must say the white text on brown background is definitely a little hard on the eyes… just might be me though.
Thanks for the great article!
I’m about as late coming to the Django party (first install last night) as I am in commenting on this post, but I wanted to throw in another perspective.
I heard about Django not too long ago at a Refresh talk entitled “Programming for Designers”, and there’s lot of talk online about how Django is perfect for them right-brainers, like myself.
Now, I’m a designer and developer, or at least my boss thinks so, and I do all kinds of fun presentation-end nonsense. CSS, JavaScript, ActionScript, and even some PHP… no problem… but I look at this Python stuff and my stomach starts tightening. You ask me to open the command line and I’m looking at you like you’re asking me to grow my own food.
Anyway, lately, I’ve gotten to where I want a better solution for a CMS than my ghetto CURLing online spreadsheets. So, I installed Joomla. Checked that out and OMG I felt like my arms were ripped from my body! (No, no, no! Mountain comes to Muhammad! I control the interface! Template is -my- b*tch!) It’s also complete overkill for the little brochureware sites I crank out in my spare time (that I don’t want to maintain). And that’s why Django caught my eye.
But, dude, install is for crap. I want a GUI, plain and simple. Don’t care how easy it is to sudo this or that… I’ll happily be a perennial Unix noob… but you underpinnings guys have a special aptitude that, though I appreciate, I have no interest in learning. I loathe the prompt and that I have to open terminal every time I want to start the server or create a new project? Coder, pu-lease! At least Joomla has MAMP. Wax on/wax off.
Also, this Python stuff is giving me hives (indents, wha-?). Do I actually have to mess with it to get modules/packages working in Django? Why can’t I just drop a folder into a folder and it just work? For the love of Pete, not another language!… I already have AS3 to contend with.
I’m just starting out with the Django, but from what I’m catching on to in this thread is that Python isn’t my father’s PHP… and I can’t just toss Django in a client’s existing GoDaddy account (why is it always GoDaddy?!) and it just work. What kind of weird setup are we talking about? What if I -only- have FTP access? (to that paranoid client’s account), PHP still works in that case.
So, at the end of the day I guess I’m saying that though I’m sure I will come to love Django (maybe half as much as the esteemed author of this article), please DO NOT refer to it as the perfect environment for designers.
Now, I’ve exaggerated a little in my comments, but this whiny fear of the backend is what it’s like for web designers. They don’t do what you do. And if you can hide that “ugliness”, it will go a long way to putting treads on Django’s tires. Indeed.
sorry about the tone … just pure frustration.
I agree with the comments here that documentation on Django (and even Python itself) is severely lacking. And the learning curve of Python and Django is pretty steep.
PHP is so much easier and its documentation ten times better. The php.net website documentation is filled with examples that work and comments from the PHP community (basically the whole world). Yes, anybody can go the the php.net documentation pages and make a comment. That’s the spirit of FOSS. By contrast, Python seems like proprietary software! Maybe the Python team does not want to make good documentation so that they can make money from consultancy?
I can appreciate that Python (and Django) is definitely a more ‘advanced’ language than PHP. But what is the point when most Python websites are very slow.
Zope/Plone is so slow that even ASP looks fast. Go to any website built using Python and you will notice that whenever you click on a link, the browser takes a long while before loading the new page. But the new page does load faster than PHP though. But overall Python sites are slower than PHP sites.
An example : http://www2.ljworld.com/ This is the website built by the creators of Django. See how slow it is.
Python is slow.
50%+ of my learning curve with Django so far (three weeks, on and off) has been spent on extending the user model and getting some form of user registration to work.
I’ve gone back and forth between subclassing, OneToOne fields and Foreign keys, based on the different approaches that float around in Djangospace. I hate the fact that “there’s more than one way to do it” as much as I hate Perl. James Bennett’s django-profiles and -registration seem to be the ticket, but boy do I have a hard time getting it to work.
More generally, getting simple things to work in Django often seems to require deeper knowledge of specific internals and conventions. “Want to take this baby for a ride? Just put in the spark plugs you prefer, adjust the distributor to get the ignition right and off you are.”
There’s such a thing as “conceptual integrity”, where the stuff on the top layer is complete, documented and operational on that same layer, without reference to layer -3. In this respect, I’m sorry to say I’ve found Django to be a bit of a disappointment.
Oh, one more thing: the basic model/url/view/template framework in Django is powerful and simple enough for a relative newbie such as myself to understand and use.
So I find I increasingly stick to that basic level — and re-invent and rewrite all sorts of relatively low-layer stuff for myself. In a way, it seems to become my “top layer”. Because it seems to take more time and effort to find, understand and integrate additional functionality — both builtin and “pluggable”.
This is not just about user reg, either. I’ve moved “down” the stack working with web forms (from admin to generic models to handbuilt models), with data (manage.py sql app…) and with authorization.
Rewriting basic functionality for myself may not violate DRY, but for me, as an incidental developer, DROP (don’t repeat other people’s work) is a much more important quality in a framework. :-)
thanks
I couldn’t agree more
Bonjorno, jeffcroft.com! nuynjrgo, acquistare cialis online, njnwcamk, cialis vendita, tatpqngy, Come vendita cialis generico nella testa diminuendo la caduta dei capelli e facilitandone la ricrescita. Dove vendita cialis isezbwbx qwsicgqz acquisto cialis generico : spyfrdvd smhnhjly ivwqrriz Dove vendita cialis Tadalafil poco costoso in linea, $0.95 per la pillola Farmacia generica Italy in Come vendita cialis online Ecco un bellissimo spot che spiega i pro ei contro dell'uso del Cialis, la Come vendita cialis generico
,<???>..] jeffcroft.com is another great source of tips on this subject,???><???>..]???>
[… - jeffcroft.com is another wonderful source of advice. Car insurance claims [… -
I saw this site yesterday and got really nice product from here and a lot of information too. I will definitely visit it more and I want you all to see that and gain what you are searching for to improve your vigour and reduce weight.
Love to make beats then you should take a look at sonicpro. It works so well, i love all the beats i make.
I have been considering branching out and trying Python development but am looking for the right programming tools. I see that you mention Django quite a bit and your blog has been helpful for me to figure out if I want to make the leap into Python. Thanks for the information.
Did you even read the article? I love Django. I wouldn’t consider using another framework.
finally, I could find your article once again. You have few useful tips for my school project. Now, I won’t forget to bookmark it. :)