Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Django vs. Flask for a long-term project (stackoverflow.com)
39 points by notastartup on Jan 22, 2014 | hide | past | favorite | 72 comments


Django has loads of goodies, but for me, by far, the ORM is my favorite part.

RDB managment is the biggest snorefest in all of software development. There are some times where you have to figure out some crazy select or whatever, but for the most part it's annoying, easy to break, and it takes forever. Django lets me not think about it at all (granted, I'm not writing crazy search things either).

When I started trying out Play Framework (for Scala, because I love type checking) I was absolutely shocked at the lack of an ORM. DB managment is the most boilerplate-y aspect of writing some CRUD, and Play decides not to help you with it.

Their arguments are about "control" and how somehow "SQL is the best DSL" (http://www.playframework.com/documentation/2.0.1/ScalaAnorm).

>val id: Int = SQL("insert into City(name, country) values ({name}, {country}") .on("Cambridge", "New Zealand").executeInsert()

Who could possibly think this "DSL" is 'better' than something like

>City("Cambridge","New Zealand").save()

/endrant

I really like ORMs, and django has the distinction of having the best ORM in my book. I sincerely hope Django would never be reduced to Flask, because I care a lot more about having DB management work without me ripping my hair out than having routes or being able to put everything in one file.

EDIT: for context, I don't ever have to do complicated things with databases, mainly tedious ones, which is probably why my vision of the world might be slightly different than yours.


Interesting. Having worked with Django for 5 years, I find the ORM is the weakest component. There's no way to express trivial things like a GROUP BY clause, and falling back to raw SQL goes downhill fast, because the result object doesn't have an interface compatible with Queryset.


Ive actually found the annotate framework can do most primitive GROUP BY queries (and in the next release or two will gain a lot more power, as its a big focus). Additionally, many of the other weird queries I need can be expresset with the queryset.extra() command, which means I get to keep working with querysets. All this support is only a few versions old though, so 5 years ago it definitely was much worse.


While I disagree that the ORM is amazing (its really really annoying when you need something it doesn't do) Django models on a whole are awesome. For me CRUD stuff is the most boring and generally involves a lot of boilerplate - but after you define a model you can add CRUD functionality with pretty much zero effort. Just define some URL's and a form class (the fields are inferred from the model automatically), that's it.

If you like ORM's check out SQLAlchemy, it is pretty damn awesome.


I did run into some issues at one point (relating to not being able to use computed columns in a later unique call), which was slightly disappointing.

But I feel it does what a framework should : solves 95% of the cases well, and gives a backdoor for the other 5% (the "extra" query). I might be heavily influenced on the generally good experiences I had with the models too though.

Thanks for the recommendation, I'll check it out.


Is not that amazing. You talk like if you have never use a ORM in your life before Django's one.


I think its better for non-trivial apps, where you isolating the database code properly in a separate module using SQL, and then, say, controller or event-handler or whatever code (depending on the precise architecture), you make calls into that code with a good communicative interface. ORMs often make stuff that is already easy a little easier, but get in the way when you need to do something less simple.


Who could possibly think this "DSL" is 'better' than something like

>City("Cambridge","New Zealand").save()

I had no idea that New Zealand was a city! Can I ask how the cities of Cambridge and New Zealand are related, though? Is one like the billing city and the other the shipping city?


So use keyword arguments if you really find that so confusing:

>City(name="Cambridge", country="New Zealand").save()

Doesn't change the point about SQL.


Your "fix" doesn't make sense. I'm looking at this from the perspective of a dev that's looking at OP's code for the first time. You're telling me that I have to sift through the codebase (which I might not even have complete access to) to figure out the argument order of a poorly named entity, just so that I can go and add keyword arguments to each place I work with ORM code?

So now you have me going and editing tested, working code just for my personal preference and digging through code that I may or may not be authorized to view. Do you have any other best practices to share?


> Your "fix" doesn't make sense. I'm looking at this from the perspective of a dev that's looking at OP's code for the first time. You're telling me that I have to sift through the codebase (which I might not even have complete access to) to figure out the argument order of a poorly named entity, just so that I can go and add keyword arguments to each place I work with ORM code?

Spoken like someone who never had to deal with recordsets of 40 different values, accessed by position, passed around various functions... ORMs can be a problem, in the sense that complex queries may be harder or impossible to express, and there can be a cost in terms of performance. Snark over keyword arguments, which are completely orthogonal to ORMs, is both rude and misplaced.


Couldn't that argument be used about any function that has multiple values?

Besides, keyword arguments do solve the problem. Also, correctly named variables ( City(city_name,country_name).save() ) and , if need be, some comments all solve this issue.


You'll be looking at the code for a first time just once; you want to optimize for the guy who spends a nontrivial amount of time on code.

Furthermore, ORM queries a much more readable, and the OP's example is bad; Django ORM queries use keyword arguments all the time.


There certainly are ORMs available with Play!

I'm using one called Activate (http://activate-framework.org/) in a few of my latest projects and it's really simplified things. There's also Squeryl, ReactiveMongo, Slick...


>Who could possibly think this "DSL" is 'better' than something like

People that hate leaky abstractions.

People that understand that having the full power of SQL is better than a mediating layer -- as your needs get more evolved than inserting a simple row.

People that are not afraid to learn SQL, and know that it's exactly a DSL built for relational data.

People that trust an industry standard DSL more than some ad-hoc DSL built on top of it.

People that know they can reuse the very same SQL across many different contexts, from their code in multiple languages to the rdbms command line client itself, whereas code for an ORM not so much.


> People that hate leaky abstractions.

SQL is already a leaky abstraction over the DBMS system's particular optimizations, or haven't you heard about people rewriting queries for Postgres or Oracle because of the engine's peculiarities?

> People that understand that having the full power of SQL is better than a mediating layer -- as your needs get more evolved than inserting a simple row.

There's nothing incompatible between using SQL for that 2% of cases and an ORM for the rest

> People that are not afraid to learn SQL, and know that it's exactly a DSL built for relational data.

I don't think anyone's afraid of SQL, but I sure as hell would be afraid of maintaining hundreds of plaintext SQL queries every time I add a new column.

> People that trust an industry standard DSL more than some ad-hoc DSL built on top of it.

All SQL implementations have ad-hoc additions that are platform-specific, and most ORMs work pretty damn well.

> People that know they can reuse the very same SQL across many different contexts, from their code in multiple languages to the rdbms command line client itself, whereas code for an ORM not so much.

This is BS. I have to touch a substantially larger amount of code when refactoring SQL than when touch ORM queries.

Seriously, have you even used a decent ORM?


>SQL is already a leaky abstraction over the DBMS system's particular optimizations, or haven't you heard about people rewriting queries for Postgres or Oracle because of the engine's peculiarities?

Which doesn't detract from my argument. Since leaky abstractions are bad why on earth would you double or triple them, building another abstraction (ORM) on the first one (SQL)?

>There's nothing incompatible between using SQL for that 2% of cases and an ORM for the rest

For serious development you'll find it's not just "2% of cases". YMMV. And again, there is something incompatible: certain ORMS make it difficult or prevent it altogether, and even if they allow it you end with a hybrid ORM/SQL codebase.

>I don't think anyone's afraid of SQL

I've met plenty of people who do. Some even think it's alien, the same way some people wouldn't touch LISP syntax with a bargepole.

>but I sure as hell would be afraid of maintaining hundreds of plaintext SQL queries every time I add a new column

If you need to do that, then you're doing it wrong.

>All SQL implementations have ad-hoc additions that are platform-specific, and most ORMs work pretty damn well.

"Pretty damn well"? As in generating slow ass queries, needing 300 pages of documentation (I'm thinking of Hibernate) for stuff you can do in 5 minutes in SQL, etc?

Here's a gem from Django's 1.6 release notes (that somebody praised its ORM in the comments above): "The Model.save() method now tries to directly UPDATE the database if the instance has a primary key value. Previously SELECT was performed to determine if UPDATE or INSERT were needed".

>This is BS. I have to touch a substantially larger amount of code when refactoring SQL than when touch ORM queries.

Have you even tried to understand what it says? You can take your SQL and use it in another language, or in the DB CLI etc. Your ORM code is tied to your original codebase. No using SQL Alchemy if you switch to Java.

>Seriously, have you even used a decent ORM?

I've used SQL Alchemy, Hibernate and Django's ORM.

Never found a decent one.

But I know that connect-the-dots, Visual Basic style developers swear by them.


> Here's a gem from Django's 1.6 release notes (that somebody praised its ORM in the comments above): "The Model.save() method now tries to directly UPDATE the database if the instance has a primary key value. Previously SELECT was performed to determine if UPDATE or INSERT were needed"

I see nothing wrong with this; almost all tables have automatic sequences for PK insertion. The proper idiom for creating a new instances is the model.objects.create() method, and save() supports the force_insert argument. This is a valid optimization and reflects the use case of people who are using the framework.

I've been developing web apps for over half a decade, some of them pretty massive, most for regular businesses. The number of times I have needed to drop to SQL I can count with my hands outside of the limited domain of reporting.

If you need to use SQL for regular old CRUD behavior, either your models are not being properly normalized or you're using a shitty ORM, and neither SQLAlchemy nor Django are bad ORMs. If your problem is that your domain object is spread across 15 tables and you actually need all those joins, there's always methods that invoke the necessary SQL and return the encapsulated objects, but like I said, you have bigger problems there than worrying about your query abstractions.


I don't understand why people want to compare Django and Flask.

Django is ideal for the freelancer or developer that needs great tools available at their disposal for quick and high-quality development.

Flask is ideal for the large system and application where many components are expected to be built bottom-up and extra flexibility is needed.

The intersection point for both use cases goes to the point where you're having several people working on a project full time, and at that point you'll likely have much more important things to be concerned about.


It's unfortunate, but many developers have the mindset of "The bigger the Application, the bigger framework I'll need!" When in reality you're better off with the opposite.

This is compounded by the fact that there's a much greater amount of service-style applications (Single-page web or mobile app backend) where a significant portion of Django's niceties (and there are many) are irrelevant to what you're trying to accomplish.


I think that he meant that Django has a bigger ecosystem with a lot of different apps, so you don't write everything from scratch. There are apps for migrations, building a REST api, having a tagging system, integration with search engines and many others. I won't comment on the state of the Flask ecosystem, because I don't know it, but I imagine it's smaller.


Here's the reality though: so many of those apps in the ecosystem are half-baked, unsupported, and don't actually work. It's a mess trying to match existing code to a set of customer requirements, all the time with the customer saying "Can't you just use django-foo?" ignoring the fact that django-foo was last upgraded 5 years ago and won't work with anything newer than django 1.4, and doesn't do half the things in their requirements anyway. It's pretty rare that any of those applications in the ecosystem actually save me any time.


There are plenty which are production ready and good quality. Some examples that I use are haystack, compressor and rest-framework. If the customer tells you to use a shitty app, explain to them why you can't. They don't know better. You're the expert.


The reason why I checked both out was because I wanted to try my hand at Python and see what all of the hoopla was about.

Unfortunately for me, the most memorable part of the experience was repeatedly calculating how many times I could have coded the exact same solution in PHP in the time it took me to finish a Flask project.


I actually have the same sensation, only for me it is about how much faster I could crank out a solution if I was using Flask or Tornado. Django is probably fine for proof-of-concept style applications within a certain set of requirements, but too often it gets used for applications beyond its scope.


So you're saying that you would be more productive in a language that you've been using for longer.


I've had similar experiences with Ruby - I used Sinatra to write a really simple REST API, and while getting the core stuff working was relatively simple, there were many times towards the end when I wished I'd just written it in PHP.

Oh, and don't even get me started on deployment.


PHP deployment gets really painful at decent scales. The process model is very poor leading to both high memory usage and high server load.


How?


Because basically the interpreter starts from square one on each request. While some things can be held over (e.g. db pconnects) it's far from ideal.


I think we should get started on deployment considering how often it's swept under the rug as something that the "lowly sysadmins" have to deal with.


I would kinda disagree here. Django's killer app starts (and almost ends) at the admin functionality. It's inferior to most other mainstream frameworks in other respects...but the admin is absolutely world class, which can be a huge time saver. I'm working on a commercial app now that has zero customer UI aside from the admin - which is used to configure a REST api.


Except the "killer app" Admin is derived from the coherence and functionality of the parts of Django. Without the ORM, or the templating structure, or middleware, or templatetags, or how apps are structured, etc. the admin would be little more than Bootstrap.

As such, the killer app of Django is Django.


Disagree. They're nothing about that combination that is special. It should just as easily have been built using, say, Jinja templates and SQL Alchemy ORM.


Not even a little bit.

Saying, "Oh, I could do that with X" is a bullshit statement. You could build an Django-like admin in Fortran.

Yes, you can hack together an admin tool in any templating system, using any ORM, or even raw SQL if you like. It's all just CRUD operations, and provided sufficient/consistent abstraction you can make it work, for your own project, without any troubles. You could, with sufficient work, even create an admin as simple as the register command.

This is the power the ecosystem at play though. When I snag a Django app to add to me project, it comes with an admin. I don't have to cobble one together.

I can replace the Django admin with an api-compatible alternative like Grappelli or Suit, and 98% of all the applications out there for Django will go right on working.

So the admin is not a killer app (per se) but is an example of how Django itself IS a killer app, because the admin is powered by it, and the community enabled by it.


I'm very confused by your argument. What is _special_ about the Django templating and ORM that enables the admin, besides "invented here"?


The special thing is the conventions.

The admin depends on uniform URL conventions driven by the framework and the URL reversion mechanism to get object URLs.

The CRUD DB functionality depends on the models being compatiable with the Django ORM interface, as well as the forms and the interations between the ORM and forms which allows for things like ModelForms.

The admin has its own set of important template tags to render information depending on the context, and that allows for consisten overriding and enhancing of functionality.

The imporant thing is that, even though all those components are decoupled, they were made in mind to interact flawlessly, and share idioms and interfaces that allow them to work together in ways that that more decoupled frameworks do not.

Finally, while there is nothing special about each component per se, most people seriously exaggerate the shortcomings of each, and there is no component in Django that is plainly bad, something that I have personally seen in pretty much every other framework I have worked with. Consistency is important.


It turns out that you have a Flask-admin plugin:

http://flask-admin.readthedocs.org/en/latest/index.html

I haven't used it, but looking at the quickstart, you gain a lot of flexibility in exchange for a bit of boilerplate. As I haven't done any Django in a long time, I cannot comment on how complete it is, but it shows that you can absolutely achieve this kind of functionality in a framework with a tiny core.


That's a huge huge statement saying its inferior to most other mainstream frameworks. I would love to know what you are basing this on as I would find it hard to make that statement.


Templates inferior to Jinga/Haml/pretty much anything that isn't ERB or XML based, DB ORM inferior to SQLAlchemy, etc. I'm not saying they're terrible, but they're certainly dated and don't reflect current state-of-the-art.


But that's not the point of Django; even the disadvantages (which admittedly exist) are pretty minor for even the worst cases.

The best thing about Django is that all apps respect the app structure, middlewares, URL dispatch mechanism, and template tags, so it is trivial to create detachable, modular applications and use them for your own project.

I can download one of dozens of applications that improve upon the provided functionality and the chances of there being an incompatibility are minor. Installing apps is trivial, migrating all your new applications' schema is consistent.

People truly underestimate just how imporant it is to have a framework with no surprises and consistency. This is something that Flask does not provide and weighs heavily when you need external functionality.


I wouldn't say they're always that minor. Comparing Django static assets with e.g. the Rails asset pipeline is like stepping into ancient history. Rails has a lot of developer quality of life stuff that is just snowballing.


I would say that Rail's asset pipeline is a contentious issue at best; not everyone needs, wants, or considered compressed assets to be a best practice, although I agree that some framework for support asset pipelines would be fine.

In any case, there are several extremely good 3rd-party asset pipelines


the admin stuff is really killer, but I think the ORM deserves mention as well (see my rant).


That seems more like a rant against Play (which I would mostly agree with). But e.g. SQLAlchemy ORM makes Django's look like almost a toy.


SQLAlchemy makes most queries significantly longer to write while not adding anything for 95% of the use cases. The fact that it's more powerful doesn't change the convenience of the Django ORM, and the fact that in practice it's not a problem.


No. Django is "The Web framework for perfectionists with deadlines". Sometimes you just need to get things done, and not to optimize prematurely.

And seriously, if you replace every Django component with something else you probably picked the wrong tool for the job.


That's actually the root of my issue with django. It's a vanilla MVC framework with a scaffolding admin interface and an ORM layer. It's popular because it's relatively easy to get started ("the Rails of python"), and thus too often it gets picked by default. The problem is that too often my customers have already picked it, have run headlong into development, then I walk in and have to ask why they picked django when their requirements don't match any of its architecture assumptions.


This last past year, at DjangoCon US • Chicago, I had the pleasure of sitting at the same table as Jacob Kaplan-Moss for the Speakers dinner prior to the conference. Very cool experience. My first.

I brought up Flask and asked him what he thought of it. I had recently used it for a project for the first time and likely only did so because I was SUPPOSE TO BE FOCUSING on Django and preparing a talk about it. So naturally, I procrasinated and did everything but. It's been on my radar for awhile. I was attracted to it by it's documentation. Turns out, I really enjoyed it. It felt familiar because I've used Django for so long. I brought this up at the dinner table.

Jacob said something that took me by surprise. I can't quote him exactly--the wine and drinks were too good that evening, but it was something to the effect of "Flask is what Django should have been". Another fellow from our table chimed in and added "If only Django had existed before we created Django!" What he ment was, without Django, Flask wouldn't of had such a clear and smooth start. Django taught us a lot.

What I took from this was, both have their place and we have a lot to be thankful for, especially coming from the Django community. In regards to longevity, I think community is a major factor but these two technolgoies are both under Python, and I think the Python community at-large is what matters here. Hearing what Jacob had to say on Flask was sobering. There is no end-all-be-all, and both of these technolgoies have more in common than not.


    if you go with django, then in the long term, 
    you will have to replace almost every single component
    of django with something else, the only remaining part 
    will be the url mapper.
That has been exactly my experience with a project and it has eaten a lot of time It is the single reason why I'm abandoning Django. Batteries are included, but they are Double DD batteries when I need AA, AAA, etc, etc.


I feel the other way around, granted I've played around with Django more than Flask. But the first thing I do when creating a Flask app is pretty much pip installing a bunch of packages to cover the basic functionality Django already provides like an ORM, forms, admin etc.


For what it is worth, I think Django just needs to be updated in a sense. For example, instead of just form.as_p and form.as_table, they should have form.as_bootstrap which you can do separately anyway, but of course that makes it a separate other thing that I need to reach for.


Same here, the remaining is the URL mapper... which I really dislike BTW.


no. what's there to discuss? the only part of Django that is reasonable to replace is the template system, which can be replaced without difficulty or loss of functionality.

Its fine if you decide that you don't want to use Django and build a more modular stack with components of your choice. If you decide to use Django you're deciding that you want to use Django's ORM, URL routing, util libraries, etc. These are all really high quality components that do their job well. There's no good reason to replace them once you've started using them.


I can assure you that there are big sites out there using Django and "not replacing every part of it with something else"

Yes, there is a need for manual SQL queries sometimes, and heavy caching, but for the most part it works ok.

I'm not sure I can disclose the exact company, since I left them recently, so I won't, unfortunately.


I wish the pyramid project, http://docs.pylonsproject.org/projects/pyramid/en/latest/ , would get some more love in the larger community. It is a really great python web framework which gets a lot of things right and is easy to extend and customize. It doesn't enforce specific project layouts but is still easy setup and get going. I have used it now on 3 projects and they have all been very successful.

edit: some background on pyramid's design: http://docs.pylonsproject.org/projects/pyramid/en/latest/des...


It is correct according to the rules of stackoverflow but the wording "closed as not constructive" is still w r o n g.

"Closed because there is a fair chance it will not be constructive" maybe? "Closed because this and this and that person felt there where a fair chance it would not be constructive?"

Oh, by the way: discourse is still a sandbox it seems: from http://try.discourse.org/ - "THIS SITE IS A SANDBOX – it is reset every day"


That's the Discourse demo site. What's wrong with resetting it every day?


Well, I don't think the choice of framework matters for a large project. What matters is the language, and both use python. Frameworks are only starting point. When you build a large software, there would be many things that framework cannot cover up. No matter how frameworks organize parts of a large software, it's not enough. You should organize by python way, not by django way or flask way.

Django app concept? It's good, but what if a single app grows too big? Split two apps? Then what if a project has hundreds apps? We should break down with python modules and packages for a large software.

Flask is simple, and it's good for beginners. But is the simplicity helpful for a long-term project? It saves only learning curve of first week.

Django supports many features and that's also good, but it only saves time to develop the features. Because flask already supports a lot, the saved time would not be much for a long-term project.

Django or Flask matters only for small projects, such as one month long. The choice doesn't matter for a large project. Yes, django template sucks, but you can change to mako or jinja or something else. You like django ORM? That's a good news, but even if you don't like it, you can use SQLAlchemy in django. Such changes can be wastes of time for short-term project, but no problem for large projects.

Code pythonic. That's the answer.


> We don’t think it’s a universally reasonable suggestion to write “small apps” in a “small framework” and “big apps” in a “big framework”. You can’t really know to what size every application will eventually grow. We don’t really want to have to rewrite a previously small application in another framework when it gets “too big”. We believe the current binary distinction between frameworks for small and large applications is just false; a well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework.

http://docs.pylonsproject.org/projects/pyramid/en/latest/nar...


When I am teaching someone programming from scratch with Python, I usually get to Flask by day 3/4. Other than having to use decorators that look confusing at first, it is very intuitive and a quick win for newcomers looking for results.


I don't really get the whole push to minimalist frameworks, from people that say Django is too bloated. It takes up 46 Mb of disk space on my machine. That is nothing these days. If you don't need a component, don't use it.


I think it's a misunderstanding stemming from loose terminology... and the code size thing is resultingly a strawman.

Bloated also tends to mean things like "takes up way too much conceptual space". Which is a valid argument against a lot of frameworks. The idea being: i have to learn to think about the problem in the framework's way, and restructure my solution around it.

The opposite being: with micro-frameworks I can just wrap my app with the framework and get some functionality out of it that would otherwise be difficult or boiler-plate.

(The counter-counter being: then you end up having to reimplement a buggy version of a full framework anyway as requirements grow and change...)

The real solution is to not think of it as either/or , but as "both, sometimes".


The other counter argument: You have features, A, B, and C. FullStack Framework 1 provides A+B+C, Lightweight Framework 2 Provides A+C, Lightweight Framework 2 provides A+B, minimalist Framework 4 provides B only. Are you better off learning (and keeping in your head) framework 1 only, or 3 smaller frameworks, which still doesn't cover the C+B case.


I would say that learning the full framework also has the advantages, that

A) It works together. The framework is a framework as a whole, so you can expect all the components to work together, without having to fudge things, or crate workaround for things that don't want to play nicely together.

B) There should be some consistency in the components and the way they are used. That should theoretically lower the cognitive load, if that's the "bloated" that people are complaining about.


Code "size" is readily measurable, and it's really easy for people to try to turn their "I like X because reasons!" argument into an empirical-looking "X is better because numbers!" one by citing it.

See also people who pore over "hello world" benchmarks, etc.


And even then, a lot of that code size is not code, but localization files, which are not exactly small.


It depends where you're coming from. Coming from ASP.NET, Django is almost minimalist. Coming from putting together a simple site using PHP without a framework, Django can look bloated, and Flask will look appealing.


I think it's more in terms of code space. With flask you can arguably write the one-file webapp


ORM - you'll write a little more code with Flask + SQLAlchemy to get the same result as using the Django ORM. With Flask, you'll have the flexibility of being able to, say, change a repository implementation to use NoSQL for some set of your models.

Authentication - Django provides UIs that you can skin/replace, and there are Django applications to do OAuth for you. With Flask there are plugins, you have to provide a UI (and UI workflow).

For almost everything Django can do, there is Flask plugin.

You might be able to put together simple sites faster with Django, you will get more flexibility with Flask.


I've mostly been doing Django stuff. But I had a really hard time scaling my Flask app beyond a single file, I just didn't get how to structure my code.


When I first read about Django's documentation, I found its notion of "apps" brilliant. It turns out that Flask introduced blueprints a while ago:

http://flask.pocoo.org/docs/blueprints/

Like the rest of Flask, it's well thought-out and flexible.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: