
Why Django Sucks - kenneth_reitz
https://speakerdeck.com/u/kennethreitz/p/flasky-goodness
======
jerf
Problem: Django has features. These features, _horrors_ , reuse each other's
capabilities.

Solution: Use something that has no features.

I'm not sure myself how sarcastic I'm being, to be honest. There's some truth
in there too (or I wouldn't have posted this). But _of course_ your
microframework doesn't have any dependency issues. Rip all those things out of
Django and it wouldn't have any dependencies either. Put them all into Flask
and it will inevitably have to choose between either having the same problem,
or leaving vast swathes of functionality on the table because of the refusal
to let the components work together so they stay separate.

~~~
kmfrk
Spoelski has a great rant about frameworks and the concept of abstractions ad
nauseam: <http://discuss.joelonsoftware.com/default.asp?joel.3.219431>.

In a way, frameworks are inherently stupid, but who's to decide where between
assembly language and x layer abstraction people should work in?

I think people who criticize Django have yet to make up their minds about what
a framework is all about, and what, if anything, it's for. They just hold on
to their utopian idea of what their framework should be.

Django was created for practical purposes by people who used it in publishing.
I think that's a great foundation for a framework - _for some people_ \- and
piling on it is just a stupid bandwagon.

\---

 _EDIT:_ I found a better way to put this: the author doesn't have a problem
with Django; he has a problem with the concept of frameworks.

~~~
detst
> he has a problem with the concept of frameworks

I'd say it's more of a problem with frameworks as they exist today. I'd like
to see a movement to REST API service frameworks with some level of
cooperation to get compatibility for standard client libraries.

Everything then gets built around services: from static site generation to
single-page apps, third-party developer APIs to admin interfaces. Then you'd
have flexibility to replace any piece of the architecture, whether to get
better to performance from a service or to use the latest JS single-page app
framework.

~~~
xxpor
Jeff Bezos recognized this 10 years ago:

[https://plus.google.com/112678702228711889851/posts/eVeouesv...](https://plus.google.com/112678702228711889851/posts/eVeouesvaVX)

His Big Mandate went something along these lines:

1) All teams will henceforth expose their data and functionality through
service interfaces.

2) Teams must communicate with each other through these interfaces.

3) There will be no other form of interprocess communication allowed: no
direct linking, no direct reads of another team's data store, no shared-memory
model, no back-doors whatsoever. The only communication allowed is via service
interface calls over the network.

4) It doesn't matter what technology they use. HTTP, Corba, Pubsub, custom
protocols -- doesn't matter. Bezos doesn't care.

5) All service interfaces, without exception, must be designed from the ground
up to be externalizable. That is to say, the team must plan and design to be
able to expose the interface to developers in the outside world. No
exceptions.

6) Anyone who doesn't do this will be fired.

7) Thank you; have a nice day!

~~~
taligent
I remember when people thought Bezos was mad for doing this.

Now it has meant that Amazon can transition internal infrastructure into
external AWS infrastructure and charge for it.

It really is genius and wouldn't surprise me if this becomes the future of how
enterprise companies develop software.

------
Apreche
I use Django and Flask quite a bit. They are the first two things I go to for
building a site. For a small site, usually without a database, I mostly use
Flask. For a large site with all the common features like auth and such, I use
Django. Yeah, it has its bad points, but that's ok. It's worth suffering
through whatever those bad points are because it has one gigantic good point.

You don't have to reinvent the wheel.

That is the fundamental problem of all micro-frameworks. They are so small
they are incomplete. You may not like Django auth, but Flask has NO AUTH. You
have to go get a third party auth system, or write your own. That means with
Django I can get a site, with auth, up in just a few minutes. With Flask, you
have to write a login page for the 1000th time in your life. It may be very
simple to do that, but it's even simpler to do nothing at all.

~~~
drivebyacct2
I think his point is that this: "You have to go get a third party auth system"
is a good thing. That way if the auth implementation needs to change, it can
more easily if it's loosely coupled to the application.

~~~
anthonyb
Django's auth system is not that hard to hack on if you need to - in most
cases you just need to write a custom backend and implement a few methods on
it. It's certainly comparable to writing your own, or downloading something
and integrating it.

~~~
Orf_
I wrote my own to use SQLAlchemy models you define: [http://tomforb.es/using-
a-custom-sqlalchemy-users-model-with...](http://tomforb.es/using-a-custom-
sqlalchemy-users-model-with-django)

Its really not that bad or hard to do at all.

~~~
anthonyb
But now you have an auth system that's tightly coupled to SQLAlchemy. How is
that different from the regular system, other than you're using SQLAlchemy
rather than Django's ORM?

I'm also finding it hard to think of a use case where you need to authenticate
100 users at once, so your initial rationale (100 separate updates) doesn't
really work. Surely you'd use a different tool to populate your database, but
Django's ORM for day to day stuff?

~~~
zzzeek
Pyramid has an auth system not tied to any ORM or persistence system
whatsoever:
[http://pyramid.readthedocs.org/en/latest/tutorials/wiki/auth...](http://pyramid.readthedocs.org/en/latest/tutorials/wiki/authorization.html)

I'd say that's better than anything hardcoded to a fixed database schema.
There's a whole world of development that has no interest in using a mediocre,
off the shelf database schema in lieu of one that is designed exactly for the
problem at hand.

~~~
anthonyb
Er, that looks pretty hideous to me.

I guess the idea is that Pyramid exposes a lot of the internals so that you
can tweak it, but what's going on in that code is completely lost in the
noise. From all of the hits that I can see on Stack Overflow, I'm not the only
one who finds it hard to understand.

Not to mention that it completely punts on adding any sort of persistence for
user models or password hashing. I stopped trying to figure out what was going
on when I realised that

    
    
        headers = remember(request, login)
    

actually returns the raw headers as a list of strings, and you need to feed
them manually back into the response.

Compare to Django's login, which is a lot clearer, even though it includes all
of the things that the Pyramid version skips over:
[https://docs.djangoproject.com/en/dev/topics/auth/#django.co...](https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.login)

~~~
zzzeek
When I look at django apps they are often similarly hideous to me. (edit: such
as - when hundreds of objects are pulled into memory, then filtered further,
or processed one at a time, when the entire thing could be done in one query.
They'll do this not only because the Django ORM isn't capable enough to do the
work out on the query side, but also because the programmer isn't SQL-aware
enough to know that's even how it should be done. Django's lack of capability
is matched by the developers lack of awareness, and the conclusion for such a
developer is "django works great!" This is why SQLAlchemy users get annoyed by
Django and Django users get annoyed by SQLAlchemy. There are two totally
different ways of looking at problems going on).

This whole thing is about where you're coming from and what software
development traditions you subscribe to. We know full well django isn't going
anywhere and you can rebut all you want, the alternatives aren't going away
either.

~~~
anthonyb
Well, when I see code like that, I see lots of moving parts, all with their
own weird API, interacting in odd ways. You just have to know that thing X
takes a string, an object and a callback function, and there are twenty thing
Xs, not five.

Complexity breeds bugs like rabbits; if you can't look at something and
understand what's going on (potentially drilling down into an abstraction or
two), then it's going to be a maintenance nightmare.

If you can come up with something that's easy to use _and_ powerful, like the
declarative_base stuff in SQLAlchemy over the top of the Mapper/Relationship,
then I'm all ears - but if complexity is the price that I have to pay for that
then it's not an easy tradeoff to make, and in a lot of cases you're better
off with the easier, worser solution.

A quick question: do you have any idea of how much work it would take to port
SQLAlchemy to Django properly? ie. so that all of the fancy Django manage
commands work. I'm assuming a fair bit, but it might be a good way to get some
sort of help as far as SQLAlchemy goes. Or you might be happy to continue
forging ahead solo, I don't know. Just a thought ;)

~~~
zzzeek
> A quick question: do you have any idea of how much work it would take to
> port SQLAlchemy to Django properly?

There is a version of this I have in mind that would take at least 6-8 weeks
of pretty solid developer time. A new layer would be built on top of
SQLAlchemy ORM that would look just like Django mappings/QuerySet. The
mappings wouldn't be too difficult, QuerySet maybe a little more.

The advantage to that approach would be that existing Django mappings and
QuerySet code could be reused in the context of a SQLAlchemy session
conversation, that is, the unit of work/identity map paradigms would be
brought in. A lot of the "bolted-on/doesnt-really-work" code I see to
approximate these features in a tool like JohnnyCache wouldn't be needed
anymore.

I'm not sure that this really encompasses "manage" though, I'd have to
increase my familiarity with that tool to know everything it does.

------
espeed
Monolithic frameworks complect things -- see Rich Hickey's talk "Simple Made
Easy" (<http://www.infoq.com/presentations/Simple-Made-Easy>).

Monoliths also lock you into a certain paradigm. Django locks you into a RDBMS
if you want to hook into all of Django's components like auth, admin, etc. And
being locked into a paradigm limits the types of problems you can solve and
makes it difficult to shift when a new paradigm emerges.

We're in a period of rapid development in datastore technology. If you're
locked into a relational database, it makes it difficult to switch and take
advantage of these developments. Loosely coupled components like Flask follow
in the Unix tradition and free you from these bounds.

Django was well positioned 10 years ago when the RDBMS ruled, but with the
proliferation of new DBs and data storage services, it's not well aligned with
modern architectures.

~~~
cheatercheater
So yeah, let's use VertexDB for auth.

...are you out of your mind?

~~~
espeed
Evidently you may be trapped inside yours -- I made no mention of VertexDB nor
did I suggest any particular database.

However, for example, Datomic (<http://www.infoq.com/presentations/The-Design-
of-Datomic>) is interesting, which is distributed and uses Amazon's DynamoDB
storage service.

~~~
cheatercheater
I'm yet to see a Django based website that outgrows any old rdbms for _auth_.
Care to back up your claim that it's bad? Same for _admin_. You do realize
that Django's admin is just a search result of objects defined in its ORM, and
that objects defined in its ORM are very obviously stored in an rdb - right?
What would you like admin to use for managing data stored in an rdb? There's
barely anything other than the models being managed that touches the database.

Edit: just before my comment gets skewed, my question is: why would you ever
use django for a website big enough to warrant this sort of worry? Let's
recap: big websites make money which is used to hire coders. Those people are
at that point probably porting your website to Agda, or some other cloudscale
technology. Sounds like you're the same kind of person who complains that Bash
doesn't support OpenMPI and that JavaScript doesn't do fib() well enough and
that this here carpentry hammer can't break diamond. Wrong application, dude.
Django is for medium-small websites, not for your Cloneddit, Clonebook,
CloneSpace, or news.yclonebinator.com; get a different hammer.

~~~
espeed
It looks like you're new here. Make sure you understand the context before you
go trolling else you might be mistaken for a chatterbot with all the non
sequiturs.

~~~
cheatercheater
I'm not new to Django or programming in general, though. Making generic
statements like your original post and catering to hip trends is one thing,
backing up your bs is another. Obviously you can't answer the direct and very
simple questions I stated, so you resort to pointing out your paltry 3.79
karma average in an attempt to sage me. Nice.

~~~
espeed
My comment was about simplicity and paradigms, with allusions to Thomas Khun's
_The Structure of Scientific Revolutions_
([http://en.wikipedia.org/wiki/The_Structure_of_Scientific_Rev...](http://en.wikipedia.org/wiki/The_Structure_of_Scientific_Revolutions)).
You must have missed that because you're trying to pick a fight about
scalability, which has nothing to do with my original comment.

Most of my work is with graphs so, for example, if you want to use a graph
database to build a social graph with a Bayesian network, you wouldn't use
most of Django's components such as auth and admin because they're tied to the
ORM -- most of Django would just get in your way. It has nothing to with a
Django-based site "outgrowing" auth.

Try to break out of your relational mindset and understand the thread before
you decide to go off. And regarding my "paltry 3.79 karma average," you do
realize the median for the leaderboard (<http://news.ycombinator.com/leaders>)
is 3.975, right? Again, know what you're talking about.

~~~
cheatercheater
Given a very specific need of working with a bayesian network based on a
social graph, i can see how your point was almost-valid. However, there's no
mention of this sort of thing in your top post. The original link is about
breaking up web apps into services, a'la amazon. I think it is you who does
not understand the topic at hand, but that's a fairly trite way of
argumentation, so let's just say that you didn't mention your very specific
needs which were needed to appreciate just _why_ not using an SQL db for auth
is _simpler_. The fact is that it's probably not, it's just that it fits your
solution better, so the total expense is lower. Having _auth_ or _admin_
backed by an rdb is not more expensive, _auth supporting your idea_ or _admin
supporting your idea_ which are two executions of the concept that are very
unusual compared to what is _normally_ done with Django. Again, you're
complaining your hammer can't be used to screw in things. Get the right tool,
or if it doesn't exist make it. Django is not the right tool. So the whole
thing is a composition of "why didn't you say so" and barking up the wrong
tree.

Of course, the lack of actual motivation in your top post can be explained
through being inarticulate as in the paragraph above; it can also be explained
by you trying to mesh together a few easy and hip claims. The later motivation
could well be something you worked hard to muster up only after initial
critique, and given that its connection to the top post hinged on a shaky
premise I think that's what has happened here.

Regarding your "paltry 3.79 karma average", the leaderboard is sorted by karma
amount, not karma average. There are people on that list who have about 10x as
much karma average as you do. And even the guy with the least karma on that
list still has over 4x as much karma as you do. Well done computing the median
of a biased subset of people. Biased because it selects people with the
largest amount of points which easily comes at the expense of post quality.
Please read about the bias of controlled, not-randomized studies before you go
throwing around statistics you can't interpret. I suggest looking at the tree
graph found on page 7 of "Statistics" by Freedman, Pisani, Purves, since you
like graphs so much. Coming up with meaningless numbers will only shut up
someone troubled by innumeracy, and I am not affected.

~~~
espeed
Damian, I think I see the disconnect here.

The OP/thread is part of an ongoing conversation about the Python community at
large and Django's stronghold on the community mindshare because a large
portion of development resources goes toward the Django platform rather than
to decoupled, external libraries (as noted in the talk).

Most new Python Web developers choose Django as the default option because
that's where the mindshare is (hence the repeated "we'll use Django, of
course" in the slides), and Django's design and momentum lock the Python
community into a certain paradigm, even though new paradigms are emerging.

Kenneth's talk, my comments, and similar comments by people like Mike Bayer
(<http://news.ycombinator.com/item?id=4079892>) were about breaking that
stronghold. My example regarding graphs was just an example for you, but my
original comment was about the bigger picture.

BTW you were the one throwing around karma average. Have you looked at yours,
and are you aware how it's calculated? -- it's not really a good indicator to
use when trying to discredit someone.

~~~
cheatercheater
At first you have tried argumenting with completely unrelated facts, then
tried ad-hominem, then you have tried and failed at coming up with a
speculative interpretation of your own original post in a failed attempt to
pretend those were your motives. Finally, in a last-ditch attempt, you have
strongly detracted from your top post.

> The OP/thread is part of an ongoing conversation about the Python community
> at large and Django's stronghold on the community mindshare

No, it's not. The highest rated top posts for this link talk about complex
monolithic code vs flexible code made out of bits which is however lacking in
features. This includes the post you're trying to defend using this detraction
strategy. The question of Django having or not having mindshare in the python
community is secondary to this, and isn't even a topic of the largest minority
of comments I've seen on this link.

To support your claim that it's all about community you come up with a short
post that is several levels deep, and purport that the original talk bemoans
the fact that Django is domineering the community. The talk barely mentions
that Django is just a popular choice, it is your completely disconnected
analysis that he was complaining about Django's harvesting of the "python
mindshare". In fact it mentions Django because according to the talker it's
just the top competitor to what he's selling. This is standard course of
action when you're presenting a new contender in a space and has nothing to do
with "the state of the python community".

In the same way as you try to paint over the past repeatedly changing what
you've meant with the original post, you do the same with the side discussion
of karma. If it were really as unimportant as you say, why were you defending
it in a post just above? You lack consistency.

Yes, I have looked at my karma average. The same page that displays it will
also show you that I barely, if ever, post here, and if you try harder you
will find out that I've registered about a year ago to post on my own content
after it submitted here. This should in fact display to you that this website
is not as important to me as you think it is. It's not that I'm new here -
it's just that I'm not, you know, "a part of it". However, your comment was
just so disconnected from the discussion, I felt compelled to point it out,
and I'm glad I did so, because the resulting trainwreck should give you, and
other people here, some fodder for thought - not everyone buys your junk
logic. You can see it as a pedestrian bystander jumping in to rescue people
from a car crash. Not a member of emergency services per se, but the situation
warrants action strongly enough that some bystander felt the need to do
something.

Threatening people with your amount of experience, jumping around in the
supposed meaning of your point, ad hominem (oh, now my comment means this..
no, it means that and you don't get it because i'm so much better than you..
oh, no, it means something else; oh btw, I've been stalking you, watch out!)
don't really form a way to have creative and intellectual discourse with
anyone. Glad to stomp that out for you, you may thank me later once you've
become accustomed to actually admitting when you had made an error, rather
than feeling the need to spin it, pretending it's something else.

In my mind, when I made the original comment to your top post, the fallout
looked like this:

(original premise): you say that it's very bad that you have to use an rdb for
admin

(baiting answer): yeah, so let's just use (nosql database chosen as an
especially ridiculous example)

(your answer): you would need to use a nosql database for admin to do (fringe
application)

(my answer): but (fringe application) is not what Django was made for. Wrong
tool.

(your answer): ok, here's a better illustration. We truly do need Django to be
able to do (some thing which is tied to an rdb), but it's much better done if
it were in its stead using (some nosql technology).

This workflow has happened (except for the last part), but it came with a lot
of bickering and manipulative speculation, which makes me think that you
hadn't even noticed it, much like someone who after getting a speeding ticket
attributes it to police depravity and oppression of the common man. Therefore,
I decided to point it out. Is it really so difficult to admit when you've shot
off on a tangent? I liked the link in your top post, quite a lot in fact, but
the comment that followed it was of no or negative value because you have
chosen to illustrate with non-examples: concepts that do not support your
claim. In addition you did this because you really really like nosql databases
and probably feel the need to bash on everything that uses SQL from the angle
of it using SQL, and sometimes can't control this need. In this way your
nature has really messed up the execution of your intentions. I'd have totally
upvoted you had you just made a link and no comment, and probably defended the
link adamantly from anyone criticizing it. I'd have loved it even more had you
accepted that maybe what you thought wasn't entirely correct. But neither of
those two things happened. Instead, you bicker and manipulate, finally
resorting to trolling through stalking, hoping that you'll find out my name
(it's not Rumpelstiltskin) and somehow shock me or make it more personal. And
even worse, you fail at stalking, but while doing that show yourself as a big
jerk. And I'm not saying I wasn't being negative, but I'm trying to keep form,
whereas you display somewhat of a sleazy, vaguely adversarial, win at all
costs quality in your discourse, which shows lacks of consistency. Consistency
is the most important thing when conveying information, and without it you end
up being viewed as a charlatan. Think about it.

~~~
espeed
Here's the problem -- you fixated on this:

 _(original premise): you say that it's very bad that you have to use an rdb
for admin_

...but it's not what I said; this is what I said...

"Django locks you into a RDBMS if you want to hook into all of Django's
components like auth, admin, etc"

I'm not saying that it's bad that you have to use a relational database for
auth, I'm saying that if you don't use a relational database and the ORM then
you lose admin, auth, third-party apps, etc. Strip all of that out and what do
you have left? See slide 71 (<https://speakerdeck.com/u/kennethreitz/p/flasky-
goodness>).

And I have said this several times before
(<http://news.ycombinator.com/item?id=2911275>), so no, I am not trying to
retrofit my argument.

 _The talk barely mentions that Django is just a popular choice, it is your
completely disconnected analysis that he was complaining about Django's
harvesting of the "python mindshare"._

If you don't think that's at least the subtext of what the presentation was
about, look at the slide for Kenneth's primary thesis: "Open Source
Everything" (slide 10 - <https://speakerdeck.com/u/kennethreitz/p/flasky-
goodness>). And then go through the presentation again to see what he means --
"Single Code Bases Are Evil" (slide 45).

~~~
cheatercheater
The slide just says "open source everything". How you conceived that this in
turn means "django has ingested the python community" is beyond me. Probably
the same mental flaw that makes you a stalker. Why should I be replying to a
stalker again?

BTW, did I mention: "stalker"?

------
btipling
The benefits of using Django include not having to rebuild a lot of boiler
plate features again and again. Things like the admin panel for example. When
I used web.py I always had to build some kind of way to manage users easily.
Login pages, logout pages, error pages.

I do not know much about Flask and it looks like it has some bare bones
middleware and context processor tools, but it doesn't look like it does much
more than what web.py offered, well except for all the testing tools (which
look pretty cool).

Sure the article has a good argument about separating components, but before
you propose your alternative you should include all of those features
(decoupled I suppose) that Django does for you already. In addition the
patterns page[1] on the Flask documentation is basically a cookbook for things
that Django already does, and by the way encourage the one code base
architecture this presentation argued against.

[1] <http://flask.pocoo.org/docs/patterns/>

~~~
anthonyb
Heh. Who needs

    
    
      python manage.py syncdb
    

when you can write a function:

    
    
      from contextlib import closing
      def init_db():
          with closing(connect_db()) as db:
              with app.open_resource('schema.sql') as f:
                  db.cursor().executescript(f.read())
              db.commit()

~~~
zzzeek
wtf is that ?

edit: using the current toolchain it's:

    
    
        alembic upgrade head

~~~
anthonyb
It's from Flask's recipe section:
[http://flask.pocoo.org/docs/patterns/sqlite3/#initial-
schema...](http://flask.pocoo.org/docs/patterns/sqlite3/#initial-schemas)

edit: not if you're using sqlite, since alembic doesn't seem to try too hard
supporting it.

~~~
zzzeek
> not if you're using sqlite, since alembic doesn't seem to try too hard
> supporting it.

Because its brand new, written by pretty much one person (I'll give you a
hint, it's me), and also sqlite barely supports migrations itself
(<http://sqlite.org/faq.html#q11>). You're trolling pretty hard in this
thread, maybe you should let other toolsets besides django have a chance.

~~~
run4yourlives
Sorry, wait a second. You're comparing a feature built in to the core of
django to something brand new that has a support team of one person and
accusing the other guy of trolling?

I'm sure your code is fine, but you can't possibly argue that it is on par
with a major component of a major framework and be taken seriously.

~~~
zzzeek
alembic and sqlalchemy are not only on par with django's tools, they are
generally superior. This isn't just my opinion, here's Alex Gaynor, Django
core committer, saying the same thing:

<https://speakerdeck.com/u/alex/p/why-i-hate-the-django-orm>

Yet the developmental resources SQLAlchemy and Alembic are a tiny fraction of
what Django has. It's the tremendous gravitational pull of Django and the
habits of its community writing things hardcoded to Django that suck the life
out of other projects in the Python community.

------
raverbashing
Personally I'd say:

\- Error handling: Django error page is great, unless of course it's a AJAX
request. Pylons does this in a much smarter way

\- Django ORM is awful. Easy to use yes, but awful

\- Django Auth is a "good intention" but awful implementation

\- Django templates are sloooooow. Jinja 2 is an order of magnitude faster

Amongst other warts

Also, the author apparently found the hard way: _don't use Django as an api
server_

I may sound critical of Django, but I think it's a "complex framework for
simple usages", I mean, if you need low flexibility go for it, you'll do what
you want really quickly.

~~~
jbm
I think you are being a bit harsh by using the quickness of Django as a 1 line
throwaway - the entire purpose is for it to produce quick, simple
applications.

There is an entire class of problems (mainly enterprise-related) for which the
simplicity (ORM / Auth / etc..) is great. I managed to tie Django Auth into
Active Directory which made the user's experience (relatively) seamless, as
opposed to the previous reality (everyone with a different password for
different applications).

Can't you also use Jinja templates in Django?

I'm not convinced that I would use Django on a large project where I get to
cooperate with 15-20 other programmers, but if the scenario is 3 people with
relatively normal business requirements it makes a lot of sense.

YMMV.

~~~
wahnfrieden
You can use Jinja2 with Django, but you lose the ability to use any prebuilt
Django templates. Which isn't much of an issue in practice since those are
often the first thing you write yourself from reusable apps.

You also can't use templatetags from reusable apps (or Django itself) but it's
easy enough to write a wrapper for those that allows you to.

We switched to Jinja2 for Canvas because the Django templates were atrociously
slow, and it was absolutely the right decision for us.

------
arthurbrown
I'm not quite sure I understand slide 48 which talks about constraints. Does a
text editor have more or less constraints than an IDE? I would argue that it
has less constraints, however I assume he is arguing that text editors are
better which implies that they have more constraints. The same goes for
Pen&Paper vs digital notes. Surely being able to write in any direction at any
size with any style as well as draw means there are less constraints than
simply typing a digital note. Am I misunderstanding which side of these
examples he's actually advocating? How does OSX v Linux enter into this
whatsoever?

~~~
tomkr
I was at the talk, and the way he explained it was that the first column
allows for less customization. Kenneth said that if he would use Linux he
would spend all day tweaking it, and not getting work done. The same goes for
pen & paper notes over digital notes, once they're written down, you're not
tweaking them anymore. A simple text editor does not have all the fancy
functions to play with that an IDE does. So he is indeed advocating the first
column, with regards to them being tools that are not as configurable as the
second column.

~~~
gbog
> he would use Linux he would spend all day tweaking it

That is a fatigued point. I use Linux and store the few tweak I have to do
manually in a install_note file. Next time I want a fresh install I just
follow the doc and in 10 mn I have a fully adapted environment. Then I do not
tweak anything more at this level. All subsequent tweaks are vimrc and bashrc
modifications that are pushed to bitbucket, and I guess I would do those on
MacOS anyway.

Being able to fiddle the config do not mean you have to, and the days are gone
when Linux was not that stable.

The thing I actually spend a lot of time tweaking for the few days I have a
new device or OS version is my phone (Android). On these little big guys I get
back the tweaking excitment I got with my first PCs (Oh! Look, you can change
the prompt! Look, you can move the start bar to the top!)

I think what is actually interesting with mobile phone is that they are not
stabilized, a lot has to be invented for them, and each new OS version or even
some apps really add new possibilities.

But for Linux, Windows or Mac, no new exciting thing is in sight, and spending
too much time tweaking the config just mean you have time to spare.

------
bryanh
Traitor scum! Such an intense title after such a nice conversation on the
Django Podcast... [1]

Of course I'm kidding because these are valid critiques. Django's code base
has a bad case of introducing really hard to debug interactions. But, to be
fair, those are fairly rare.

However, as a Django lover I must say that Flask is missing a lot of what I
love about Django: sane _pre-built_ options for getting you to 90%
functionality quickly. That last 10% can be difficult, but that is better than
a more difficult 90%.

One thing that is rather annoying with Django is the learning curve (there's a
lot in there), but the docs are so good that it isn't that bad (and one could
argue that Flask is harder to learn because it means learning SQLAlchemy,
Werkzueg, etc... too).

As he mentions in the slide, best tool for the job. Flask is certainly more
Pythonic (IMO) and beats Django very handily for simple apps, but the ability
to skip reinventing the wheel will keep a lot of people in the Django camp for
the foreseeable future.

[1] [http://3rdaverad.io/shows/django-
podcast/episodes/deployment...](http://3rdaverad.io/shows/django-
podcast/episodes/deployment-for-humans-with-kenneth-reitz/)

------
hcarvalhoalves
I've been working with Django for about 5 years now and I can say it's a great
framework for a "quick win" when your use case matches its original intent -
that is, if you're building public websites, with a custom CMS backend, and
need the usual stuff like authentication, feeds, comments, etc. You can go a
long way by just using and extending built-in apps - and for the 20%-40% left
you find some great 3rd party libraries for doing what you need.

From my experience, the problems arise when you begin bending it to fit your
particular use case. For instance: Django is naive regarding multi-tenancy,
something you usually need when building web apps, so you'll have to hack some
parts in it; the coupling of most 3rd party apps with the built-in
authentication app can also get in the way; etc. If your use case deviates
_too much_ from the "website" model, using Flask (or just going down to WSGI)
for the plumbing and then picking best-of-breed libraries (SQLAlchemy, Jinja,
etc.) can pay off in the long run as opposed to going with monolithic Django
from the start because, down the line, you'll find you had to hack most parts
anyway.

------
antihero
I love Django for making websites, but I'd go with Flask for an API. The only
issue I found with Flask is I often found myself recreating stuff that Django
already does, and is already done way better.

------
majormajor
I think the "Constraints are Good" slide is massively oversimplified.
Especially the "editors vs IDEs" and "primes vs zooms" bullets.

Just for one example: stepping through an IDE's debugger, integrated into the
code editor, to track down a problem is incredibly handy. It's a habit I
picked up while living in Eclipse doing Java work, and why most of my Rails
work is now in RubyMine instead of Emacs like it was when I was in school.

And sure, if I had unlimited resources, and wasn't annoyed at all by having to
carry around a bunch of primes, and could change lenses in an instant (or was
carrying four different bodies too), I'd rather have a set of excellent primes
than a zoom.

Very much like how I'd love to be able to integrate (and possibly write
myself) a bunch of services to perfectly fit my problem instead of using a
framework. But it just isn't very practical for a lot of areas. And then the
problem changes, and the purpose-built solution to be adapted... and then this
happens a few more time and how perfectly have you maintained your original
separations of concerns?

~~~
tonyarkles
This is diverging a bit, but weaning yourself off of the debugger habit can be
incredibly liberating. I used to be a debugger junkie, but I've changed to a
system of carefully reading code and understanding what it does (and often
writing unit tests to confirm that each pieces is doing what I think it's
doing). Every time I have to go into a debugger now, I curse the person who
left me with no other choice (say, due to design choices or laziness).
Sometimes... the person I curse is me :)

~~~
Xion
I wholeheartedly agree. TDD as Test-Driven Debugging is the way to go. :)

------
brown9-2
I'm confused about the assertion that Flask is only 800 lines of code.

Counting Flask v0.8 with cloc yields twice that:

    
    
      $ perl cloc-1.56.pl flask --exclude-dir=testsuite,ext
      18 text files.
      18 unique files.                              
      114 files ignored.
      
      http://cloc.sourceforge.net v 1.56  T=0.5 s (36.0 files/s, 8008.0 lines/s)
      -------------------------------------------------------------------------------
      Language                     files          blank        comment           code
      -------------------------------------------------------------------------------
      Python                          18            694           1748           1562
      -------------------------------------------------------------------------------
      SUM:                            18            694           1748           1562
      -------------------------------------------------------------------------------
    

And that doesn't include the size of Werkzeug, without which Flask cannot run:

    
    
      $ perl cloc-1.56.pl werkzeug --exclude-dir=testsuite,ext,debug,contrib
            20 text files.
            20 unique files.                              
           126 files ignored.
      
      http://cloc.sourceforge.net v 1.56  T=1.0 s (20.0 files/s, 13460.0 lines/s)
      -------------------------------------------------------------------------------
      Language                     files          blank        comment           code
      -------------------------------------------------------------------------------
      Python                          20           2307           4277           6876
      -------------------------------------------------------------------------------
      SUM:                            20           2307           4277           6876
      -------------------------------------------------------------------------------
    

Including the contrib and debug packages of Werkzeug adds another 3000 LOC.

~~~
the_mitsuhiko
I haven't done the numbers in a while but from the given ratio I would assume
your line checker tool treats docstrings as code. The red part there is for
the most part just documentation, not code:
<https://github.com/mitsuhiko/flask/blob/master/flask/app.py> (as an example)

~~~
brown9-2
I think you're right, it is counting docstrings as code.

------
sorensen
While it is true that Django may be quite a large framework, a 'kitchen sink'
in a way, I feel that many people often miss the point of what a framework is,
in that you don't have to use all of it.

In my few years of developing in Django I have had my frustrations and joys,
many of the frustrations coming from the idea that I should do things how the
framework wants me to, only to realize that it is still python that I'm
writing code in. The idea of Django is not to be some utopian framework where
all of your pythonic dreams come true, it is to enable you to build
applications quickly and with ease.

While Django may have been created to be a publishing platform, our primary
use for it is a genetic analysis application, which is complicated enough
without having to worry about the framework, and trust me, Django is not
anywhere near a problem in the app. We also use Django for a separate report
delivery system, which has API endpoints and is constantly being fed data from
3 other applications, and again, Django has never been an issue.

Sure, you can roll your own libraries with something small like Flask, and
reinvent the wheel many times over, but do you actually get features rolled
out? Or are you constantly patting yourself on the back for keeping such a
small codebase while maintaining a home-grown system and hoping you can get a
feature out the door while fixing all of the bugs that not only the system may
have introduced, but your features as well.

Here are my biggest worries of a very customized/home grown framework: 1) Does
the knowledge of the framework transfer to the next project you work on? 2)
Are you writing documentation so that the next person can understand the code?
If so whats the time cost for that? 3) Are you spending more time building the
perfect system or rolling out features?

Don't get me wrong though, I love working with small polished libraries and
connecting them together, namely in node.js, but it is entertaining more than
productive.

------
tferris
This is not about Django and why it sucks. It's a refreshing take on
monolithic vs. micro frameworks and it's nice to see that a micro framework
like Flask gets the attention it deserves.

I believe that monolithic framework are aged too. Django and also Rails as
monolithic as they are force you into given patterns, even if you can choose
specific modules. I made my first experiences with a highly modular micro
framework (Node with Express) some weeks ago and I have to say that I don't
want to go back. Even if it seems that you have to reinvent the wheel
sometimes (but in reality you don't) your application reflects your use case
much better, it's more fun and you are again programming yourself—deciding on
architecture, structure and design patterns.

------
zeeg
I think the title is misleading, but the slides/concepts are pretty spot on.

------
ashray
I think something the author didn't really cover was upgrades. When elements
are highly decoupled, it's easy to go and upgrade piece by piece. API changes
can be factored in and dealt with relatively easily. (I believe this is
something Amazon did right as well..)

I know this for a fact because upgrading a massive django deployment from 1.1
to 1.4 was a huge project for us.

That said, I still love all the out of box defaults that django provides and
the fact that extending them is relatively painless as long as you spent a few
years learning the ins and outs of the system ;)

------
EternalFury
All frameworks are horrible. Because there is no 1 ring to rule them all. The
more "powerful" frameworks become, the more abstract and detached from reality
they become, the more you end up solving problems that exist only because you
are using said frameworks.

Clearly, there are building blocks that are useful across most applications.
You can gather those into libraries and reuse them over time. But,
frameworks...no, there are no silver bullets, no fat-free fat, no sugar-free
sugar, etc.

------
jrochkind1
What you're asking for is awesome, but.... it's really hard to do well. The
extra abstraction is hard to get right. Instead a bunch of decoupled
components playing well together, you can wind up with a bunch of chaotic
components having their dependencies changed out from under them, and
seriously raising the barrier to entry for newbie developers who need to
figure out how to put humpty dumpty back together again to actually build an
app.

Rails 2->3 tried to the general route you're talking about (but still with
language API connections, not REST. That would be even harder in some ways)
--- with, well, mixed success. And Rails starts out lower level (much less UI
built-ins) than django, another thing that would make it even harder.

I've had many failures in personal homegrown projects. :)

Abstraction is hard. To do super high level of architecture abstraction _well_
takes experience and skill, as well as more developer resources. It's easy to
go off into architecture astronaut adventures, and you end up spending all
your development time trying to keep the parts working together, significantly
sapping resources to actually, you know, provide new functionality.

That said, there is certainly such a thing also as too little abstraction and
too much tight-coupling too, obviously. There is a happy medium.

------
ezl
_sigh_

I understand that "why django sucks" is a better, more provocative title that
will get read more than "why django isn't perfect in every way and i prefer
using flask for this", so i don't fault the author for choosing that subtext.

However, the general "tradition" (yes, its a tradition now) of justifying a
tech/infrastructure decision with _"Ah! language/framework/db made popular by
others is a horribly broken mistake! you are doing it wrong!"_ is 1. getting
old, 2. counterproductive for engineers.

They are tools. There are different tasks with different requirements. They
have different pros and cons and different learning curves. Some tools are
better suited for some tasks. Some tools are even better suited for most
tasks. Sometimes it even makes reasonable sense to use a product that isn't
the best of the best of the best if you are really certain you don't care
about the dimension in which your tool is not the most amazing.

Hammers are bad for cooking eggs. Spatulas are bad for nailing nails. I made
eggs this morning. Keep an eye out for my upcoming blog post: "Why hammers
suck!!"

~~~
sashahart
I completely agree with you about needlessly provocative titles.

On the other hand, in the world of frameworks, it's not entirely common for
the use cases to be (as) disjoint as they are for hammers vs. spatulas. More
often, frameworks overlap in functionality and differ on matters of style and
ideology. And this is what feeds the flame wars.

For starters, you have a choice between MyKitchen and spatula. MyKitchen has
everything you need to make a reasonable pasta meal for up to 8 guests. The
pasta practically serves itself... even when you are making steaks. spatula is
totally dedicated to scraping things out of pots, and obviously you could just
use MyKitchen.SpatulaFactory(_ctx) instead (you did read the equipment
manifest, didn't you?) Plus MyKitchen has a plugin which will make pork buns
that practically serve themselves... why waste time with low-level stuff like
spatulas?

Some guy graduated from spaghetti to pizzas and he can only scoff at spatula,
which is not necessary at all, since you can cook pizzas directly on the rack.

Another guy made this incredible pocket-sized leatherman which includes
compact versions of all the kitchen tools including a camp stove.

It is true that most frameworks are better suited to some tasks than others,
but for a given task one might be just plain technically inferior, or only
different in some stylistic way.

Not that style doesn't matter, if it makes you feel happier doing your job.
Otherwise, why bother with Ruby or Python when there is already Java EE or
COBOL?

~~~
ezl
agreed that it is more subtle than hammer vs spatula, but just trying to
illustrate the point that this general flavor of X sucks compared to Y isn't
instructive.

flask is great. but if you want the admin, then you have to build it yourself.
i've used django formsets ONCE, ever, but when i needed them I'm glad that
django had them instead of me having to build them on flask.

then i've used flask for awesome projects that i knew in advance i didn't need
that stuff.

different needs, different tools.

~~~
sashahart
I agree that Django vs. Flask is not a matter of what sucks or is broken.

If I think a hammer looks nice but someone informed explains that it is
designed in such a way that the head will tend to fly off, I find that very
instructive. The many broken spatulas on github are also instructive.

If you want a pre-built admin, Django provides for a different need, yeah...
but if the needed stuff is in the large overlap between Django and Flask, you
can't just say "different needs" because you are considering competition to
satisfy the same needs. (For example, Flask is promoted for HTTP APIs, but
Django also has some good packages for putting together HTTP APIs, so that it
is hardly clear that Flask would always be the better choice for APIs).

Most of the argument (here as in emacs vs. vim) is in matters of taste or
philosophy - or a dead heat between valid technical concerns. tastypie or
Flask? I submit that it matters more what makes you happy and productive, so
that it is entirely valid to choose Flask, or Django, or both. After all, it
is your life you are spending on all this, you should be happy. If you hate
emacs, there are alternatives.

------
markessien
Django is just _badly designed_. Many things in Django don't work right from
the start, and changing them is a big, big pain. When I tried Django, I had to
make some changes to the authentication (I can't remember well, but I think I
wanted to be able to sign in with email addresses). It was a big pain that
took quite a while, and made it incompatible with the rest.

In the end, as the application grew, I had to throw out most of Django and
just use my own custom written code. Steep learning curve for a process that
will be thrown out later anyways.

A micro-framework is much better. At least you can mix and match as you want.

------
EnderMB
The biggest stumbling block for me, and I imagine a lot of other users, is
simply getting it installed and running. On Ubuntu I was able to do this
within ten minutes, but if I choose to develop on Windows it's next to
impossible to get a Django project with a PostgreSQL db running without any
issues.

I'm quite fond of Python and I like what I have used of Django, but I'd be
willing to wager that a lot of other people from PHP land have wanted to use
Django and have been put off by how hard it is to set up.

Obviously, I could be doing something wrong, so if it's obvious that I'm doing
something wrong please say so.

------
mikepk
First I want to say that, in many (most) cases, when people ask me what python
web framework they should use, I wholeheartedly recommend Django.

Unless... the person is a weirdo, like me.

In most cases people are looking to prove some idea and they just want the web
framework equivalent of "a car that gets me from point A to point B I don't
care how.", Django gets the job done and in that capacity is really nice to
use.

Personally I don't like using Django. I like to fiddle. I like to tweak. (I
like my string beans quarantined!) I like my systems to work exactly the way I
want them to work. I have strong opinions about how things should work and am
not usually willing to compromise on fundamental issues.

Django does not (in general) make this easy. I wrote a post a while back about
the hoops I had to jump through (and the source I had to spelunk through) just
to use form field sets and to modify the error reporting
([http://mikepk.com/2010/08/python_django_forms_errors_fieldse...](http://mikepk.com/2010/08/python_django_forms_errors_fieldsets/)).

The real tipping-point for me in not using Django was the ORM. I think it's
great for getting up and running quickly but I tend to be of the "ORM-as-
Vietnam-of-software-engineering" camp. It's partially due to my OCD/control-
freak need to have maximum control and visibility of the RDBMS. I've been
converted to using an ORM by SQLAlchemy, but mainly because the philosophy of
that project is not to hide the RDBMS from you but to make it easier and more
pythonic to work with.

While Django is theoretically decomposable, you lose the ability to use many
of the plugins, apps, etc... the moment you deviate from the standard package
/ install. That's what the arrows in the slides indicate. If you're willing to
get something that nearly approximates the functionality you need, and don't
care that's it's not exactly what you want, then Django all the way.

Teh Awesome: * Get up and running very quickly * Lots of batteries included *
Great Docs * Limited config hell

The Bad: * Tight coupling of features and third party "apps" * Yes you /could/
customize things but then you lose many of the benefits of why you're using
Django in the first place * Customization breaks things * Too-strict
templating, almost-python-like-but-not-quite * ORM is of the "vietnam" variety

------
AncientPC
There's no "better / worse" framework. Django and Flask are two tools that try
to accomplish the same thing in different ways.

Django:Ubuntu::Flask:ArchLinux

Django gets you 90% of the way from the start, it's in the tagline: for
perfectionists with deadlines. However it's difficult to change certain parts
of Django.

Flask gives more control but comes at a cost. Each framework has their uses.

------
reinout
I made a summary of Kenneth's talk at
[http://reinout.vanrees.org/weblog/2012/06/06/flask-django-
su...](http://reinout.vanrees.org/weblog/2012/06/06/flask-django-sucks.html),
for some this might be nicer to read/scan than slides. The slides are more
complete, though :-)

------
kaiju
I'm really tired of seeing memes & my little pony references in presentations.
I thought we were adults?

~~~
kenneth_reitz
Adults can't have a sense of humor?

~~~
byproxy
There's humor, and there's LCD pandering. Despite that, this submission did
get me to try out Flask. Nice and straightforward to get started with, which
is good because I'm stupid.

------
yesimahuman
Thanks for posting this. I use Django extensively and I never really felt any
pain from the tightly coupled monolithic approach, but I always like improving
my tools. I will check out Flask.

Any suggestions for making it easy to build REST style APIs? Is piston the #1
choice still?

~~~
jtchang
I've used all 3 and I settled on "django rest framework". <http://django-rest-
framework.org/>

The issue I have with piston is that it didn't turn my objects into JSON
automatically for me when I returned from the call. I also had to map each and
every call (GET/PUT/POST/DELETE) and there was no default out of box behavior.
I felt like I was violating the DRY principle over and over.

Tastypie was great when I started but I wanted to do some non-RESTful things
with it. Like POSTing to /article/{id}/{action}. Yes it is not REST...I don't
care. It makes a lot of sense to POST to /article/15/publish to publish an
article. I had to override so much inside tastypie it was getting to me.

Django restframework is a bit different. Default behavior is centered around
mixins (basically multiple inheritance). I created a mixin for actions being
specified and basically added it to any resource I wanted to have that. If you
want to know more feel free to ask.

~~~
Daniel_Newby
> The issue I have with piston is that it didn't turn my objects into JSON
> automatically for me when I returned from the call.

That sounds like the perfect place to use a Python function decorator, which
lets you wrap a funtion in standard boilerplate.

------
tantalor
What can be said of Django and Flask may as well be said of Rails and Sinatra.

------
scottschulthess
Having what is essentially one app split into multiple apps is going to
introduce a whole lot of complexity to the business that isn't necessarily
unless the amount of developers on your team is very large.

------
tbatterii
the "benefits" of flask vs. django can easily be attributed to any of the so-
called web micro frameworks vs web full stack frameworks.

it's interesting to me that django seems to be getting grief for some of the
same things zope was/is. Time to reinvent the wheel again I guess.

[http://www.jrandolph.com/blog/2006/02/02/zope-vs-django-
here...](http://www.jrandolph.com/blog/2006/02/02/zope-vs-django-heres-some-
gasoline-to-put-out-the-fire/)

So surprise surprise, you stray from the happy path the full stack framework
lays out for you, be ready for the pain.

------
zem
from the ruby side of things, here's a very good write-up of the differing
philosophies between rails [monolithic, batteries-included] and sinatra
[small, lightweight]: [http://rubysource.com/rails-or-sinatra-the-best-of-
both-worl...](http://rubysource.com/rails-or-sinatra-the-best-of-both-worlds/)

the post goes into why there is room (and a need) for both in the ruby web
ecosystem, and where you'd want to use each one.

------
rapind
Not trolling, but didn't we go through this with rails a few years ago and the
result was, as usual, it depends upon the context?

------
LaSombra
I'm an inexperienced web programmer wannabe, but what's the difference between
Flask and Sinatra?

~~~
peregrine
Largest different is age and ruby vs python. That said Sinatra is built on
Rack which has a ton of extensions to add things like sessions or auth. Where
as flask has specific flask modules. Really apples to apples in my opinion.

------
jh2007
Your argument is just saying a blank piece of paper is the best framework.

------
known
Not just Django, every framework sucks for sophisticated applications.

------
powatom
Sounds to me like this guy was using the wrong tool for the job.

------
stesch
And websites that need JavaScript and don't tell you.

------
sgt
How is Flask any different from using say, CherryPy?

------
atasever
this presentation is as true as saying "e-books are bad, books are great!
Because e-books have too much functionalities"

------
bangbang
What fonts were used in this? I like.

~~~
kenneth_reitz
Thanks!

Titles are High Tower Text (Flask Logo Font):
<http://www.fontyukle.net/en/High+Tower+Text.ttf>

Text is Gaudy Bookletter 1911 (Open Source!):
<http://www.theleagueofmoveabletype.com/goudy-bookletter-1911>

And code examples are Monofur: <http://www.dafont.com/monofur.font>

~~~
tmoertel
The typography in your presentation is great, but there's one thing you could
do to make it better: don't use a left single quotation mark (U+2018) when
what's needed is an apostrophe. For that need, the preferred character is a
right single quotation mark (U+2019). "Keep ‘em Separated", for example, ought
to be "Keep ’em Separated". (Zoom in a billion times to see the difference.)

~~~
kenneth_reitz
Awesome, thanks for the tip :)

------
ianstallings
Meh, I like Django.

------
drivebyacct2
If you like this approach, and I certainly do (especially after finishing a
very service oriented django project), I fully encourage you to check out Go
standard libs combined with Gorilla. Plus you get other fun advantages of Go
if you want/need them.

------
sparknlaunch
> _"Speaker Bio Python Overlord for Heroku. Creator of Python-Requests.
> Photographer. Curator of The GitHub Reflog™. Knows where his towel is."_

Thanks for sharing. The site has a few other interesting presentations by the
same speaker.

------
zashapiro
But have you _seen_ the trailer for Django Unchained?!? (new Tarantino flick)

<http://www.youtube.com/watch?v=rC8VJ9aeB_g>

------
its_so_on
Sorry if this is a stupid question, but are these just slides without any
voice or commentary?

Also, you might be interested in this video,
<http://www.youtube.com/watch?v=i6Fr65PFqfk> "Why I hate Django" by Cal
Henderson then of Flicker. 2008 though - I'd love to know about an update
about the things addressed.

------
f0untain
Is it possible to use DSL instead of a framework ? Could we have web DSL to
easily make frameworks ?

