

The mess Django's in - niels
http://mockit.blogspot.com/2010/04/mess-djangos-in.html

======
jz
I've only looked at a small portion of the underlying django code and from
what I've seen there were definitely some complicated parts, but it was far
from being messy. Perhaps the author is confusing necessary complication with
messiness? After all, isn't the purpose of a high level framework to hide the
messy details and allow you to express your ideas clearly and efficiently?

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.

------
j_baker
I couldn't disagree more that Django's code is horrible. In my experience
(which isn't much to be honest), Django's code is a pleasure to read.

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.

------
nudge
Not sure I could disagree much more with this. Firstly, I think the power of
Django's inbuilt functionality more than makes up for whatever aesthetic
problems there might be (I haven't checked) with the underlying code. That's a
trade-off I'm very willing to take. Secondly, I'd rather go with messy code
and an active bug-fixing and development team than beautiful code that no-one
touches. Plus, there's no 'kool aid drinking' going on here. In fact there's
surprisingly little razzle-dazzle about Django. All I know is that it helps me
build what I want to build, fast, and the documentation is the best I've ever
seen for just about anything.

~~~
agentultra
You have to drink the kool-aid. Django has managed to develop all of its own
components. It's not impossible to switch out one of those components for a
better one, but you'll be fighting the framework to do it. That's because the
Django framework likes to use the Django components. If you don't drink the
kool-aid, you're missing the point.

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

~~~
nudge
Following the conventions of a project in order to take advantage of its
strengths is not 'drinking the kool-aid'. If you need custom components and
find it hard to integrate them, use something else. Nobody's forcing you to
use Django.

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.

~~~
agentultra
I should recognize what, exactly? That you're using relativism as a red-
herring? I meant what I said, thank you very much.

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.

~~~
nudge
You're not understanding me.

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.

~~~
agentultra
By taking the "it works for me" (relativist) position, you're avoiding the
central argument.

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

~~~
nudge
I'm not avoiding your argument. I'm telling you it's fallacious.

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.

------
stevenwei
I mostly agree with the author of the article: ever try to modify the User
object to accept an email instead of username for login purposes? It's a
complete hack.

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.

~~~
zeemonkee
I agree with your conclusions on Django auth (and I really hate the
UserProfile hack) - and once you start swapping out the template engine and
ORM you lose much of the usefulness of Django (as well as most of the 3rd
party apps).

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.

~~~
stevenwei
Yes if I rolled my own it would almost certainly be on top of
Werkzeug/SQLAlchemy/Jinja2.

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.

~~~
zeemonkee
The problem with something like login/registration is that on the one hand
it's a repetitive task, on the other it's something that ends up being highly
customised for each application.

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.

~~~
stevenwei
I agree that the end implementation of a User login and registration system
will be highly customized for each application.

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.

~~~
zeemonkee
Class-based generic views would go a long way as well; Django's generic views
are pretty useless in their current form.

------
angelbob
It sounds like a lot of the complaints are about their ORM layer. I'll point
out that Rails (a very comparable project) has a lot of cruft in ActiveRecord,
their ORM layer, as well. I can't directly compare it to Django's, but it's a
bit of a hairball. Some of it is just that it's hard to write a good ORM
layer.

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.

------
ibejoeb
What? How about an example?

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.

------
ubernostrum
ORMs are like sausages. You really don't want to know what goes into them.

~~~
kingkilr
Pssh, a lot more love went into the ORM than ever went into a sausage.

~~~
ubernostrum
You've apparently been eating the wrong kinds of sausages.

------
kqueue
Just because you don't understand the code it doesn't mean it is awful. I am
not defending django at all since I use webpy.

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.

~~~
stevenwei
>>> Just because you don't understand the code it doesn't mean it is awful.

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

~~~
kqueue
You are assuming that if you didn't understand the code, then no one can.
Hence, if you don't understand it, then it is awful.

What I am saying if you want to say a code is awful, then state why it is
awful.

------
lionshare
SQL and Objects are a problem in the first place. SQL is optimized when
working with sets. So unless simple one-record read/write, most queries should
fall to direct SQL which is really easy to do in Django and in Python. And for
the one-record transactions, the ORM does not really matter that much. Bottom
line: SQL is an essential programming skill.

------
Daishiman
Completely disagree. Most of Django's components are so simple that you can
tear them out and replace them for your own thing. I've done it several times
now and I never felt confused about it.

------
mdg
>Even simple things like setting up and tearing down the database is awkward.
You have to actually make an outside call to a command-line script to do it.

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

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

------
c00p3r
Google uses Django on its AppEngine, at least some parts of it. Seems that it
is not so badly written.

------
barnaby
Can't say I agree with this either.

