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:

  1. 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.
  2. 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.
  3. Admin interface: inability to delete multiple items at once. This problem still exists, and it still a pain in my ass virtually every day.
  4. 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.
  5. 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.
  6. * 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 getabsoluteurl. — 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.

Comments

  1. 001 // Trey Piepmeier // 07.25.2008 // 1 PM

    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?

  2. 002 // Ryan Berg // 07.25.2008 // 1:06 PM

    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.

  3. 003 // Jeff Croft // 07.25.2008 // 1:20 PM

    @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. :)

  4. 004 // Ryan Berg // 07.25.2008 // 1:24 PM

    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?

  5. 005 // Timo Zimmermann // 07.25.2008 // 1:27 PM

    @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.

  6. 006 // Trey Piepmeier // 07.25.2008 // 1:31 PM

    @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.

  7. 007 // Clint Ecker // 07.25.2008 // 2:04 PM

    Good post, Jeff.

    In regards to Schema Evolution, django-evolution is 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-evolution/

    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.

  8. 008 // Andrew Ingram // 07.25.2008 // 2:38 PM

    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:

    • extract/checkout Django to a folder
    • create a django symlink from python’s site-packages to the django package folder (the one with the init python file)
    • create another symlink called django-admin.py from your system’s overall usr/local/bin (or similar) folder to bin/django-admin.py

    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.

  9. 009 // Karl Peterson // 07.25.2008 // 2:44 PM

    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!

  10. 010 // Jeff Croft // 07.25.2008 // 3:27 PM

    On a unix box installation of Django is basically 3 steps…

    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.

  11. 011 // Kyle // 07.25.2008 // 5:21 PM

    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.

  12. 012 // Jeff Forcier // 07.25.2008 // 5:42 PM

    @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.

  13. 013 // Joshua Blount // 07.25.2008 // 5:51 PM

    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.

  14. 014 // Alex Holt // 07.25.2008 // 6:30 PM

    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..

  15. 015 // Jacob Kaplan-Moss // 07.25.2008 // 7:56 PM

    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?

  16. 016 // Peter Baumgartner // 07.25.2008 // 10:27 PM

    On the contrib.comment improvements front, see:

  17. 017 // Peter Baumgartner // 07.25.2008 // 10:33 PM

    Also, the pony thing has been resolved over at dpaste, although still not included in trunk unfortunately.

  18. 018 // David Z // 07.25.2008 // 11:04 PM

    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.

  19. 019 // baczek // 07.26.2008 // 12:58 AM

    scheme migration works, albeit as a third-party app. google deseb.

  20. 020 // Christoph Hack // 07.26.2008 // 2:44 AM

    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:

    • the admin creates a drop-down field, even when there are some millions of entries (maybe its now better customizable with the new newforms-admin?)
    • there are no outer joins or other more complicated queries possible
    • you get lots of lost updates, because django does updates by value and not by expressions
    • you can’t change some millions of entries at once, because of limitations of the orm
    • you need to use raw queries even everywhere, to get that what you want, but then you don’t have any mapping or dbms independence.
    • mapper limitations. (e.g. you can’t map multiple tables to one object or anythings like that)
    • the url building just sucks. Something like url_for(‘forum.index’, slug=’…’) would be great, which automatically builds the right url and checks url-rules… But thats a limitation of REs they use.
    • the templating engine they use is extremely slow and imho not dynamic enough..
    • no blobs or binary fields

    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? ;)

  21. 021 // Kevin Teague // 07.26.2008 // 3:12 AM

    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:

    $ easy_install grokproject
    $ grokproject samplegrokapp
    ... answer a few starter questions ...
    

    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:

    $ cd somegrokproject
    $ python bootstrap.py
    $ ./bin/buildout
    

    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:

    [versions]
    django = 1.1
    django.comments = 1.2
    

    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:

    [app]
    recipe = django.recipe.app
    eggs = django
           dj.supercaptcha
    

    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.

  22. 022 // poko // 07.26.2008 // 5:01 AM

    Christoph Hack,

    Django is create for small CRUD applications where did you get that from? no offence but it sounds trollish

    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.

  23. 023 // poko // 07.26.2008 // 5:08 AM

    But i think that’s only a small subset of all the things which makes Django so unusable for such projects

    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/

  24. 024 // Harshad Joshi // 07.26.2008 // 8:09 AM

    Try either web.py or cherry.py

  25. 025 // Jeff Croft // 07.26.2008 // 9:06 AM

    Try either web.py or cherry.py

    Did you even read the article? I love Django. I wouldn’t consider using another framework.

  26. 026 // Nathan // 07.26.2008 // 11:42 AM

    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!

  27. 027 // Kenny Meyers // 07.26.2008 // 4:29 PM

    @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.

  28. 028 // Ludwig Pettersson // 07.26.2008 // 5:03 PM

    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_SLASH disappearing and admin redirecting to /django.fcgi/admin/ rather than /admin/).

  29. 029 // Andrew Ingram // 07.26.2008 // 5:06 PM

    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.

  30. 030 // Mike Cantelon // 07.26.2008 // 8:16 PM

    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.

  31. 031 // Kenny Meyers // 07.27.2008 // 1:59 AM

    @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.

  32. 032 // Ludvig Ericson // 07.27.2008 // 2:04 AM

    the url building just sucks. Something like url_for(‘forum.index’, slug=’…’) would be great, which automatically builds the right url and checks url-rules… But thats a limitation of REs they use.

    It’s possible, if you mean getting a URL out of parameters. Template tag ‘url’.

    the templating engine they use is extremely slow and imho not dynamic enough..

    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, …)

  33. 033 // Jeff Croft // 07.27.2008 // 7:13 AM

    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?

    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.

    I don’t really understand the concept of symlinks either. Why can’t I just get in and start programming right away?

    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:

    1. Download the latest release from our download page.
    2. Untar the downloaded file (e.g. tar xzvf Django-NNN.tar.gz, where NNN is the version number of the latest release). If you’re using Windows, you can download the command-line tool bsdtar to do this, or you can use a GUI-based tool such as 7-zip.
    3. Change into the directory created in step 2 (e.g. cd Django-NNN).
    4. If you’re using Linux, Mac OS X or some other flavor of Unix, enter the command sudo python setup.py install at the shell prompt. If you’re using Windows, start up a command shell with administrator privileges and run the command setup.py install.

    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.

  34. 034 // Kevin Teague // 07.27.2008 // 12:22 PM

    @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!

  35. 035 // Jeff Croft // 07.27.2008 // 12:45 PM

    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.

    Agreed.

    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.

    Agreed. But, do you actually have to track down Python libraries to install Django? I’ve never had to.

    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.

    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.

    This should then give you an isolated Django install specific to that Django project, w/ correct database and python-database libraries.

    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.

    We have already solved this problem in other Python frameworks, Django just needs to play catch-up for a bit!

    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.

  36. 036 // Kenny Meyers // 07.27.2008 // 3:18 PM

    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 :)

  37. 037 // Andrew Ingram // 07.27.2008 // 3:30 PM

    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.

  38. 038 // Kevin Teague // 07.27.2008 // 3:40 PM

    But, do you actually have to track down Python libraries to install Django? I’ve never had to.

    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, you wouldn’t want to do this in the Django installation process.

    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?

    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.

    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.

    a lot of that frustration isn’t really Django’s fault, but a newbie probably doesn’t see it that way.

    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.

    I see it as marketing thing, more than anything else.

    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!

  39. 039 // Jeff Croft // 07.27.2008 // 4:17 PM

    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.

    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’ve found that setting your pythonpath and path or using symbolic links gives you a more useful environment than just running setup.py.

    I have, too. Unfortunately, this process isn’t very well documented for newbies.

    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.

    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.

    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.

    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.

  40. 040 // Kenny meyers // 07.27.2008 // 4:20 PM

    @jeff

    Fine, then Python needs to have its mySQL connector built-in among others

    cough just like Ruby cough

  41. 041 // Jeff Croft // 07.27.2008 // 5:50 PM

    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/ruby.html

  42. 042 // Kevin Teague // 07.27.2008 // 7:44 PM

    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 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.

  43. 043 // Jeff Croft // 07.27.2008 // 8:38 PM

    Kevin: Thanks for clarifying. I think I understand what you’re getting at, now. :)

  44. 044 // Kenny Meyers // 07.27.2008 // 9:55 PM

    @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.

  45. 045 // Stefan // 07.28.2008 // 1:59 AM

    I think a Django Gem would be great.

    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.

    sudo gem install rails —include-dependencies”

    It’s not that easy when you’re behind a proxy … And I am.

  46. 046 // Jeff Self // 07.28.2008 // 6 AM

    Here are the things that annoy me the most about Django.

    1. Single database support. What I mean here is you can only specify one database in a project. This has to change if Django is to make it in the enterprise. Where I work, we have data stored in DB2 databases, other data stored in SQL Server, and even more stored in PostgreSQL. I’d love to map a connection to each one in a project. I use ColdFusion primarily at work but would love to use Django, but I’ve run into situations on more than one occasion where I had to make database connections to more than one database.
    2. The developers need to find a way to integrate SQL Alchemy into Django. SQL Alchemy is a more robust ORM than the one that comes with Django. Plus it would help standardize ORM in Python.
    3. Django needs to allow for the option to use UUID’s as primary key’s. This should be configurable in the project’s settings.py file. The only thing worse than using autogenerated ID’s for primary keys is using natural keys. UUID’s make life far easier for migrating data to new systems and backing up and restoring databases.

    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.

  47. 047 // Jeff Croft // 07.28.2008 // 7:06 AM

    Single database support.

    I’ve heard several of the Django lead developers mention this one, so I know it’s in the works for a future release.

    The developers need to find a way to integrate SQL Alchemy into Django.

    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?

  48. 048 // Jeff Self // 07.28.2008 // 9:31 AM

    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/django-sqlalchemy

    I believe you cannot use SQL Alchemy with the Admin stuff.

  49. 049 // Jeff Croft // 07.28.2008 // 9:38 AM

    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.

  50. 050 // matt // 07.28.2008 // 12:22 PM

    @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.

  51. 051 // Jeff Croft // 07.28.2008 // 3:17 PM

    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.

  52. 052 // slav0nic // 07.29.2008 // 11:24 AM

    for problem2 i use this solution

    class EntryAdmin(admin.ModelAdmin):
    ...
    def queryset(self, request):
        qs = super(EntryAdmin, self).queryset(request)
        if not request.user.is_superuser:
            qs = qs.filter(blog__author=request.user)
        return qs
    

    A little simplifies for remove items (problem3):

    http://webnewage.org/post/2008/1/15/chut-bolee-byistroe-udalenie-obektov-v-adminke/

  53. 053 // Jeff Croft // 07.29.2008 // 12:42 PM

    @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.

  54. 054 // Jeff Croft // 07.29.2008 // 12:54 PM

    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.

  55. 055 // Alcides Fonseca // 07.30.2008 // 3:25 AM

    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.

  56. 056 // James Bennett // 07.30.2008 // 11:32 PM

    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.

  57. 057 // Baxter // 08.01.2008 // 11:43 AM

    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.

  58. 058 // Scot Hacker // 09.02.2008 // 1:07 PM

    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:

    • First exposure to object-oriented principles
    • First exposure to MVC/MTV principles
    • First exposure to Python
    • Learning Django itself

    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.

  59. 059 // Jeff Croft // 09.02.2008 // 3:08 PM

    Scot, I think you make some very good and valid criticisms. I agree on all points, particularly the one about terminology.

  60. 060 // justin lilly // 09.11.2008 // 3:30 PM

    I feel compelled to add that django now has a pony, thanks to Bryan Veloso. Http://twitter.com/djangopony

  61. 061 // rex // 09.12.2008 // 2:08 PM

    UUID as primary key

    Look here for a Django implementation:

    http://www.ibm.com/developerworks/blogs/page/johnston?tag=Django

  62. 062 // snirp // 09.15.2008 // 4:48 AM

    Please review the issue with the pony: it seems to have landed: djangopony.com

    Beware: the glitters do not come off easily!

  63. 063 // Stuart // 09.17.2008 // 7:04 PM

    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!

  64. 064 // Diego Verde // 10.14.2008 // 9:20 PM

    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.

  65. 065 // binnen // 10.26.2008 // 8:56 AM
    1. unfortunately, the documentation is a shame at certain places. e.g., when it comes to handle inlines, overriding form & formsets etc. usually, the examples are simple and don´t address real-world problems.
    2. from my point of view, the core developers are not interested in improving the admin-interface. important tickets are there for over 2 (!!!) years. this is just unbelievable. still no support for ordering inlines - which really pisses me (and my customers) off on a daily basis. still, not able to translate app-names. still, not able to define the order of apps/models for the admin index page. still, no admin-support for orderwithrespect_to. and probably a lot more I just can´t remember. and yes, I would definitely provide patches, but then - see point 1.

    sorry about the tone … just pure frustration.

  66. 066 // ron_paulite // 11.10.2008 // 11:39 AM

    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.

Post your comment