The mess Django's in
mockit.blogspot.com
mockit.blogspot.com
I have read and understood all of web.py and am currently buried up to my head in rails actionpack routing code, both contain some hairy bits of code. By pushing all these messy details down into the library they allow the application developer to be more expressive and concise. As long as there are tests, comments, and documentation to back up the complicated bits, I don't have a problem with a library or framework not being obvious to understand at first glance.
That said, I do think that a case can be made that Django's architecture has some definite warts. Whether or not they are a huge deal is largely a matter of opinion. For instance, I do agree with the author that Django does have a bit of an overreliance on import-time side effects. I particularly don't like the fact that I can't even import some parts of Django without having a settings.py defined. On the other hand, I don't know how difficult it would be to change it.
(I'm the author of the 2007 article.) I disagree with you about the Django codebase. Overall, it's well-written, well-tested, and extremely well documented, so much so that I consider it a case study of "what to do with a free software project".
It's a decent framework for what it is and has a large community behind it. Some of the best marketing in a Python project I know about.
Just from memory, the last time I looked at the ORM code it was pretty bad. There were functions that ran on for hundreds of lines without comments or docstrings. Plenty of introspection being used to bypass encapsulation. It wasn't impossible to follow, but it did look a little haphazard and "thrown together" (as opposed to thoughtfully planned out and designed).
SQLAlchemy otoh, is a really good example of well designed and clean code. As far as ORMs and database interfaces go, they have some very clear ideas and concepts they've built up from.
The "mess" I think Django may find itself in is that there are frameworks built on third-party libraries that are easier to use and better to use than Django. Its ORM isn't as great as SQLAlchemy. Its templating engine isn't as great as Mako. For a framework as large as Django I think they will find it harder and harder to keep up with what everyone else is doing as long as they continue to believe that they can "code it all."
Your thoughts about the templating engine vs Mako, and the ORM vs SQLAlchemy are subjective. You should recognize this. I don't mean that one is not better than the other. I just mean that 'better' is really 'better for you and what you want to do'. For me, Django is perfectly sufficient. Similarly subjective is the value you put on 'clean code'. I happen to value a community that tests and makes sure it all works. That is also subjective. Don't confuse your preferences with actual problems with something you are evaluating.
Django works for me, very well. I didn't drink any kool-aid. If it doesn't work for you, that's fine. But if you think the fact that it doesn't work for you, or meet your standards, means that the project is in a mess, then I think you are the one missing the point.
Not everything is created equal.
SQLAlchemy's ORM is just better than Django's ORM. Better in the majority of objective metrics you can think of. The code is well designed, structured, and documented. It supports better features and more databases. It's not just better because "it works for me."
I didn't say that the Django project itself "is a mess." It still has a great community and leadership. It still has great marketing and strong appeal for a niche audience. What I did say was that Django may find itself in a mess when competing frameworks provide more than Django can offer because they rely on a community of components that individually are better than those offered by Django.
I should mention I base my hypothesis on years of experience developing large and small sites and applications using Django as well as a few years developing websites using other frameworks and using SQLAlchemy.
You say A is better than B, objectively.
I'm telling you that B suffices for my purposes. Given that, the fact that A is objectively better than B doesn't really matter. That fact's importance is subjective. You find it important. I do not.
So you should recognize that what you find as a fault is not necessarily a problem for others, and therefore not necessarily a problem for the project.
The OP pointed out that Django's reliance on internal dependencies and import-time side effects is a bad thing.
I agreed and added that the internal components themselves aren't bad, but that it's the superior components that other frameworks are using that makes Django bad.
There are a lot of people out there who could justify using COBOL by your same logic.
I think Mark Ramm was being more prescient than most people give him credit for when he suggested Django could go the way of Zope if it doesn't open up to the wider python eco-system.
The Django ORM isn't the best ORM available and I think it hurts Django to not be able to take advantage of better ORMs without having to sacrifice its core features (admin, authentication, etc).
Technologies don't come and go according to whether they're better or worse than other technologies. They really don't. They come and go according to whether enough people decide to use them, or engage with them, or develop them, and so on. If it were as you say then no-one would be using php, which plenty of people would agree is 'worse' than its alternatives.
I mean, you're sort of right. Your argument is just missing a step. It may be that Django's difficulty including other toolkits is a weakness. But that only matters when enough people decide it matters.
You can call that relativism if you like. It doesn't make any difference. But it could just be that Django works fine enough.
Feel free to point out how wrong I am, but if you do it from a qwerty keyboard (an 'objectively' bad keyboard layout), you'll only be proving my point. Problems are only problems when they're problems for people.
Long story short, show me a Python ORM that has clean code, and I'll show you an ORM that either supports just one database or is so buggy as to be unusable.
As for messy code in Django, well that really isn't that fair. Sure, some of the things they do with imports is, frankly, scary, but there are very few cases where this becomes a problem, and when it does, there is always a workaround. Where, in my opinion, Django's ORM falls short is it doesn't really like you to think you're interacting with a database… many things that would be very useful just aren't there (swapping out ORM-generated SQL with a hand-written counterpart, for instance, is next to impossible). The typical solution to this seems to be "well, you can get a database cursor and do as you please"… but there comes a point where this just isn't good enough.
However, if Django's ORM just can't cut it for you on a project for whatever reason, it really isn't that hard to ditch and switch to something else (like SA). Yes, you will lose the admin, and you'll lose the authentication and session components (though these are actually easier than one might assume to get working under another ORM with their 'backends' concept), but you still have an amazing framework without these components.
Reading this article seems, to me, like the guy has taken one brief look at Django's internals before going on to condemn them as ugly in this post. And that's really not cool.
Also, if you think you need a more "powerful" template system, you are probably bloating your template with code that should reside in your view functions written in python instead. HTML templates should be mainly HTML.
The project maintainers on the other hand have an incentive to make the code easy to work on. Especially if they want outside contributers. Not to mention the fact that they themselves (the project maintainers) have to work on it.
The thing is, it didn't need to be a hack, but some of the core components are really tightly coupled together when they don't need to be, so it ends up being a hack. This tends to happen a lot when you 'go outside the box' of Django's codebase.
For example, everyone says you can 'use SQLAlchemy' in Django. On paper this is true. But then you lose the admin, the user auth system, the messages system, model forms, and all of the other batteries that make Django useful.
That said, the alternatives to Django are so incredibly lacking that (for the moment), I'd rather stick with Django than roll my own everything else. Pylons and Turbogears are an ugly mish-mash of third party libraries that don't work well together. In some cases there are good third party libraries (SQLAlchemy is indeed quite an amazing piece of software), but many other pieces are lacking:
- Authentication/authorization libraries are terrible.
(You want to bury that in the middleware layer and use
query string parameters to indicate login failure? What?)
- Nothing out there is as good as Django's model forms.
- There is no equivalent to sorl-thumbnail, for basic image processing.
- The boatload of third party Django apps. Yes, most
of these are poorly written and not modular enough either
but there are some really useful ones out there like django-pagination
and django-compress.
Django is far from perfect but unfortunately, taken as a whole, it's still better than the current alternatives.Using SQLAlchemy doesn't change any of that. For pre-built components, like auth and admin, just go with the flow. You're free to use SQLAlchemy side-by-side with Django's ORM.
Do you create duplicate representations of your models in SQLAlchemy and Django? What happens when you need to start migrating your database schemas?
Forgive my lack of imagination, but I can't think of any way of doing what you suggest without it coming across like a horrible hack.
If you take away admin, auth etc I really don't see much that's compelling about Django. However you are also correct about Pylons - I would like to recommend it but the documentation is terrible and has its own share of hacks (the "c" global, @validate decorator etc).
Rolling your own isn't that painful though - you might want to look at Werkzeug. Coupled with SQLAlchemy and Jinja2 you have a really nice DIY framework for very little effort, that grows with your project. I'd also like to mention WTForms which uses a similar pattern to Django forms and is very easy to use and extend.
The Flask microframework, while just a few weeks old, is built on top of this toolkit and looks very promising, especially for beginners to Python web development or smaller projects.
The history of Flask is amusing but I'm not particularly interested in another microframework - 80% of web app development is doing the same boring shit over and over again (user logins, permissions, registration, form processing, image uploads, password resets, REST apis, etc). Microframeworks punt on all of that stuff and expect you to reinvent the wheels there.
We don't need more microframeworks in the Python world, what I really want to see is a full stack alternative to Django that took care of all of the boring stuff so web app developers could focus on the 20% of work that makes their app really unique.
My experience with Django is that you generally start with the generic login and registration views, but quickly end up ditching them when you need something just a bit different. I'm not sure what would be a better solution, and I'm not sure there is one. I've yet to see a solution that is neither a) too complex (AuthKit) nor too simplistic (Django).
Form processing and REST are a bit more low level and should be achievable by a modestly-sized framework or library.
However, I think there is a TON of reusable code out there that is shared across apps: simple things like setting properly salted and hashed passwords, providing a password reset mechanism, and a base user object with permissions and groups.
Django gets a lot of this stuff right, what they get wrong is the complete lack of customizability which means you need to throw everything away once you go outside the box.
A few simple base classes that could be extended and overridden with custom fields would solve that problem entirely - the reason Django doesn't provide this (IIRC) is because the built in auth system was written before their ORM properly supported inheritance.
Let's hope that Django can also take a Rails 3-esque approach -- make the ORM layer modular, then use whichever you like. That's a surprisingly good way to disentangle the internals of the ORM from everything else. And once you do that, it gets a lot easier to polish up the code, or if necessary replace it with something prettier.
I imagine a fair number of the Rails 3 folks will be replacing ActiveRecord with DataMapper, for somewhat similar reasons. I plan to.
The Django code is concise, readable, and pretty modular. I rarely read the docs anymore; just browse the code. In fact, I feel like a better programmer for having read most of the Django code.
This appears to have been written today, but it reads like it's from 3 years ago.
Saying the code is awful without proving why is just a way to explain to yourself why you are not understanding the code. It makes you relieved that it is not your fault. However it is your brain deceiving itself.
Blame it on yourself first then on the code.
Disagree entirely. My philosophy has always been that code is more difficult to maintain than it is to write in the first place, so one of the core tenets of well written code is its simplicity and ease of understanding.
If you write a convoluted mess that's difficult for someone new to pick up right away, it will probably also be difficult for you to jump back into several months later when you need to fix a bug or add features.
Not to mention making it more difficult for third party developers to contribute...
What I am saying if you want to say a code is awful, then state why it is awful.
... Because I want to be able to do that WITHIN my webapp?
As a side note, I wish this guy would of pointed to some specific examples instead of speaking in generalities.
It is very hard to give specific examples, most this kind of blog posts are mostly rants without anything concrete to grasp on. I guess it's mostly about what kind of coding/architectural style are you used to.
For example, I have done rails several years ago. I liked it, but just couple of small projects. Then I started my next site with django, which I liked very much. I found the django's modular system much better than rails, and it was very easy to add functionality through open-source packages and customize them for my needs.
Now I have started contracting project where I fix existing rails project, and it is kind of pain in the ass, because I'm used to django's way of thinking. But I can't give any specific reasons why it sucks, it is just my viewpoint.