
Choosing a Web Framework: Django, Flask, or Pyramid - ryan_sb
https://www.airpair.com/python/posts/django-flask-pyramid
======
mkolodny
I've built things with each, so I'm pretty opinionated on the subject.

My verdict: Start with Django; use Flask once you hit 10M+ users.

• Django -- Sensible defaults. A plugin for most things you may need. Fairly
high learning curve, but worth it. I've heard people at big startups say that
they've spent weeks building things with Flask that were either built-in, or
came as a pluggable app for Django. Pinterest still uses Django for their
middleware, but switched over to Flask for their API [1].

• Flask -- Low learning curve. Very lightweight. The go-to ORM is SQLAlchemy,
which is more fully featured, but has a higher learning curve, and is
generally less-liked than the Django ORM. Great for hackathons.

• Pyramid -- Extremely configurable. You get to (have to) make a lot of low-
level decisions. Serious lack of sensible defaults. Strong community. The IRC
channel is helpful, yet time is spent discussing why Pyramid isn't more
popular (lack of sensible defaults).

[1] [http://www.quora.com/Pinterest/Would-Pinterest-consider-
Flas...](http://www.quora.com/Pinterest/Would-Pinterest-consider-Flask-in-
place-of-Django-if-it-were-starting-today?share=1)

~~~
raverbashing
"Fairly high learning curve, but worth it"

Exactly. Apart from the tutorial there's not much of "a way" of progressing
forward (like "learn this now"). Except South/Migration. Learn this.

There are a lot of resources but it follows the Pareto rule, depending on what
you need you may need to go learn Localization/Middleware/Advanced ORM
queries/Advanced template tags and filters/Details of Requests and
Responses/Advanced forms or models (yeah, Django really doesn't help with
CSSing your forms)/etc

~~~
Veratyr
I'd hold off on South now that Django has its own migrations. They're going to
be the method of choice moving forward as far as I know.

~~~
raverbashing
Yes, that's why I said South (for older versions) or Migration (for newer
versions)

They're very similar, so learning South won't be detrimental (and it is useful
from the moment you learn it)

------
yaur
What I really want in a web framework is for it to stay out of my way. In that
regard I have been happy with Flask. All of the functionality lives in
external modules (many of which are reused in back end tools) with the
relatively simple task of HTTP interactions living in a Flask powered facade.

~~~
andybak
What I really want in a web framework is for a web framework to solve the
common problems so I can write less code unless I'm doing something unusual.
In that regard I have been happy with Django. All of the functionality does
what you'd expect and nearly everything is overridable in a consistent way
when you need to get closer to the 'metal'.

~~~
possibilistic
This is just my personal experience, but once you try to do certain things
with Django, you start to butt heads with it. Django relies far too much on
convention, and it shoehorns you into their tooling patterns.

I think the most exciting and flexible way to do things these days is with a
collection of microservices. You can do feature work independently, test small
isolable units of functionality, and achieve scale.That said, we could use
cross-cutting libraries to make microservice implementation easier...

~~~
gtaylor
We've been pretty happy with it at Pathwright. 1.7 was a great release. The
conventions aren't too restrictive, and it has been incredibly easy to get
contractors plugged in and productive in minimal time. We follow many best
practices, so our codebase is going to be "familiar" (to some extent) to
anyone with some experience. We love Django for the productivity level our
team achieves with it.

The ecosystem is great, too. django-rest-framework in particular makes us oh-
so-happy.

Not to knock flask/Pyramid/everything else. Pick what your team can be most
productive wit. I just think there are less reasons than ever to get too
caught up in choice of framework. There are so many great options now.

~~~
ryan_sb
> Pick what your team can be most productive with

Absolutely. If you already know one and like it, go forth and hack. If you're
not sure, or don't like the one you have, there are tons of great options. Not
just Flask/Django/Pyramid either. Tornado, Bottle, CherryPy, Falcon, and more
all have dedicated users (some more than others).

------
bkeroack
I'm a big fan of Pyramid because (among many other reasons) I think ORMs are a
poor abstraction and therefore do not want to be forced into using one (a la
Django). I didn't find the learning curve terrible either--it's just MVC (er,
"MVT") with some configuration/logging/routing capabilities built in.

Being able to do dynamic routing (via Traversal) is also cool. I really like
being able to attach custom objects/attributes to the request object--that
lets me write my own datalayer (without an ORM) and have it shared as a
singleton across the lifetime of the request. It's also cool that you can
write "views" (aka "controllers") either as flat functions or classes.

I personally don't write much server-side HTML munging anymore so I don't have
much to say about Chameleon templates. Last time I used them I found the
documentation a little lacking but otherwise it worked well. I still prefer
Jade.

~~~
mayhew
What do you use to query a relational database, if not an ORM? Do you build
your SQL with string concatenation? In my experience that gets messy very
quickly for complicated queries, so you end up needing some sort of SQL
builder abstraction.

~~~
bkeroack
For Mongo I write a data layer that has methods like GetFoo() or UpdateFoo()
where the methods have implicit knowledge of key structure (and query model
objects for validation, etc)

For SQL I would do something similar but use (for example) SQLAlchemy Core
(not ORM) to do DB-agnostic SQL generation. That would essentially give me a
SQL API somewhat similar to pymongo.

~~~
ryan_sb
For some things ORM's get in the way, but avoiding them by your own data layer
sounds like a pretty big time-suck.

Being able to write a single line of SQLAlchemy to build relationships into
your models seems way simpler than implementing relationships in a custom data
layer.

~~~
mayhew
Yeah, I think the sweet spot is using SQLAlchemy's ORM for simple queries and
dropping down to core for more advanced usage. Best of both worlds.

~~~
ryan_sb
Even for advanced queries (ok, not _super_ advanced) SQLAlchemy can hold its
own, especially if you're willing to dip into the sqlalchemy.core modules.

------
giancarlostoro
I'm surprised nobody shows interest in CherryPy? I prefer it to Flask, I got
more done coding with CherryPy, than I did with Flask, in less time. It just
doesn't get in my way. I guess it's a matter of preference though.

~~~
tjr
I haven't done any Python web application stuff for a while, but most of what
I have done was with CherryPy. I liked it a lot.

------
mpdehaan2
Mostly, I prefer to have things already done for me so the micro-frameworks
quickly build into added work later.

One of the secret weapons of the Django world is Django REST framework. The
built-in API browser alone is pretty amazing.

South is also a pretty darn good migrations system, and is well up there too.

I think I could take or leave the Django admin panel for an established app,
but for small apps or just getting started, it's a nice thing to have too.

We don't use Django's templating system.

~~~
chatmasta
DRF is great, but it's pretty heavy weight. I've used both DRF and Flask for
building API's. I was far more productive with DRF at first, but once I
developed my own system for flask, I much preferred bare-bones flask coding.
It's really nice to have all the code that could be causing bugs, directly in
front of you.

~~~
gtaylor
> DRF is great, but it's pretty heavy weight.

What does this even mean? It _can_ do a lot for me, therefore it's bad?

We use DRF extensively, but we don't come close to using everything that it
can do. We don't tend to use ViewSets or the auto-routing features, but the
fact that it _can_ do those things doesn't hurt us.

DRF gets so much attention from such a large community. It's constantly
improving to the point where we don't have to worry about it. If you fall
victim to NIH Syndrome and roll your own, you have to be proactive about
finding and addressing your own issues, as well as keeping up with
advancements around the ecosystem.

I'd just rather let the people who focus on DRF handle that, and we'll throw a
pull request over the wall if we run into anything that hasn't been addressed.

~~~
chatmasta
An example of where this excess bloat would be bad is in a microservice
architecture. Django has a footprint so big that using it for microservices
doesn't make sense, because at that point you may as well roll all the
services into a single application. In that case, I think DRF is great. But if
I'm building a microservice architecture, I want the API code for each service
to be 100-200 lines, not 100-200 lines + Django.

So yeah, there are efficiency gains from DRF, I agree. But (in my opinion),
the gains are far less in architectures with separate applications all using
DRF. In that case, something like Flask makes more sense to me, purely for the
benefit of debugging, logic clarity, and independence.

I recommend a great talk by Kenneth Reitz on exactly this topic. [1] (He's
given a variation on it multiple times -- just search youtube.)

[1]
[https://m.youtube.com/watch?v=U2frH932U1g](https://m.youtube.com/watch?v=U2frH932U1g)

~~~
gtaylor
> An example of where this excess bloat would be bad is in a microservice
> architecture.

Django is pretty easy to slim down. Yank the middleware you don't need, stick
to what you do. No need for stuff like context processors if you are using
DRF. You don't have to use models or the ORM at all if you don't want.

I think the line count would be very similar for many cases. For example, if
your flask app needed DB access, you'd end up pulling in and boilerplating an
ORM anyway. Ditto for sessions/authentication/etc.

------
poulsbohemian
It's too bad whenever these articles come up that Tornado
([http://www.tornadoweb.org](http://www.tornadoweb.org)) seldom gets a
mention. It's minimalist and stays out of your way; pair it up with SqlAlchemy
and you've got a complete solution. And you don't have to fool around with
wsgi.

~~~
rch
Has anyone tried deploying Flask apps with Tornado? I'm curious what the
performance and tradeoffs would be, since it might be a convenient migration
path from Nginx+uWSGI should a compelling reason to do so ever arise.

\- [http://flask.pocoo.org/docs/0.10/deploying/wsgi-
standalone/#...](http://flask.pocoo.org/docs/0.10/deploying/wsgi-
standalone/#tornado)

------
__e
We had a panel discussion at PyCon India (a little over a week back) on Flask
vs Django vs web.py with considerations for other frameworks as well.

Video: [http://www.youtube.com/watch?v=jM-
SgJTi8g0&t=6h00m00s](http://www.youtube.com/watch?v=jM-SgJTi8g0&t=6h00m00s)

------
chdir
If I were at the crossroads of choosing between Django, Flask & Pyramid, this
post doesn't tell me enough to make a choice that I won't regret later. It
doesn't go into the depths of the shortcomings that you will start noticing
when you are months into the project. Unfortunately, there's no easy way to
choose the right framework. Or put it differently, the right framework does
not exist. Although, I feel that flask has the potential to get there.

~~~
gtaylor
From a purely technical perspective, you probably can't go wrong with any of
the three unless you have super specific needs. In cases like that, you may
not even want to use Python at all.

The best way to decide which to use is to take your team and hammer out some
quick project using your 2-3 leading framework candidates. Whichever your team
is more subjectively happy with is where you should go.

There are other considerations, but so many projects fail to gain traction
after taking longer than planned to launch. Team productivity is priority #1
for us, though subjectively we've found it to be very easy to find contractors
who can be plugged into a Django project with minimal ramp-up.

------
TeeWEE
While not really a framework, i've getting used to using webapp and
appengine's ndb datastore (yes its an appengine application). The application
doesn't serve html, only json (its basically an api).

The our app is build as an ios, android and webapp on top of this api.

It depends on what you're building. And sometimes this approach is not nice.
But it works for our usecase.

In conclusion: sometimes your architecture doesn't need a full-fledged webapp
framework.

~~~
ryan_sb
Even for building a mobile backend, having a framework can help. Tools like
Cornice (Pyramid), Django REST framework, and Flask-REST can make building
API's much easier.

------
raverbashing
Here's my quick take on the subject:

\- Django: a big framework for simple projects. Batteries included (most).
Even better if it's a CMS. ORM is fine if you don't do anything complicated.

\- Pyramid: much more flexible, more "pick and choose". Also try
[http://jinja.pocoo.org/](http://jinja.pocoo.org/)

\- Flask: if you need to get web requests and do whatever you want with it.

~~~
roywiggins
If you do like jinja, it's Flask's 'native' template engine.

------
hit8run
Python + Flask is nice but has serious performance constraints. I guess I
found a bug in Flask or Werkzeug that restricts requests per second to a value
below 600 req/s. See here for more details:
[https://medium.com/@tschundeee/express-vs-flask-vs-go-
acc087...](https://medium.com/@tschundeee/express-vs-flask-vs-go-acc0879c2122)

------
teddyh
Many times when I’d like to use Django, I have to eliminate it because of one
thing: I’d like to access the database from non-web programs, and Django
certainly does not make it easy to use its ORM in a non-web context.

Sometimes I’d even like to access the database from _external, possibly non-
Python tools_ , and then Django is out of the question, since it does not
define a stable API to its database layer, only its ORM.

Therefore, I go with Flask + SQLAlchemy in these cases.

(One time, for a short-lived project, I chose to ignore that Django does not
provide a stable database, and simply let Django create the database and then
simply assumed that the database table definitions would not change during the
lifetime of the project and accessed it externally via SQL. But this was for a
short-lived project which would only run for a few days.)

------
curiously
I've been using Flask, I love it for the most part. I use PeeWee but prefer to
use just raw SQlite. It's supposedly faster with the new 3.8 sqlite version,
so I think I'm gonna stay with it.

My gripe with Flask is not itself but the other plugins like flask-security
which lacks a lot of documentation.

Flask itself is a delight to use but the only trouble is organizing the code
in separate files. I still haven't mastered it, I just import the same file
which imports all the modules in all of my flask scripts.

