In Rails, you can rip out ActiveRecord and replace it by an entirely different ORM like DataMapper. There is no real default authentication support, but you can easily plug it in. The list goes on and on: they've done a decent job (I would say 'great', but there are still some improvements needed to make it 'great') at decoupling the various components of Rails and making it easy for users to mix and match.
You need a dependency to offer a certain feature, but not necessarily the default dependency. They have internal API's that decouple the lot. That is exactly what this presentation argues Django doesn't have, but should have.
Now I don't know anything about Django, so I can't judge whether the argument has a factual basis. If you tell me it is wrong, because you can easily replace the persistence or authentication layer of Django, then I have no choice but to believe you. However, the argument is logically consistent and the viability of the alternative it proposes is backed up by plenty of real world examples.
Don't take my word for it, all of this is actually written in multiple places in the docs, tutorials and/or Django site, I can't remember. Here's an excerpt that exemplifies Django's philosophy (from [0]):
> Each view is responsible for doing one of two things: Returning an HttpResponse object containing the content for the requested page, or raising an exception such as Http404. The rest is up to you.
> Your view can read records from a database, or not. It can use a template system such as Django's -- or a third-party Python template system -- or not. It can generate a PDF file, output XML, create a ZIP file on the fly, anything you want, using whatever Python libraries you want.
> All Django wants is that HttpResponse. Or an exception.
> Because it's convenient, let's use Django's own database API, which we covered in Tutorial 1.
Indeed, Django components are incredibly convenient to use, and readily included, and officially supported. But they're completely optional.
[0] https://docs.djangoproject.com/en/1.4/intro/tutorial03/#writ...)
I think you missed the point. In Rails, ActiveSupport does a whole lot of automatic magic with ActiveRecord. But it is not limited to ActiveRecord, as most of that functionality is factored out into ActiveModel - implement those interfaces and your link helpers and whatnot will happily support nonAR models. I use this quite often to represent things that doesn't reside in a database.
Well, most of the time. There are a few things out there that are not migrated to ActiveModel yet that really should be (the model side of datehelpers in forms comes to mind).
As for the comparison with Rails, faking models is the same in Django, as both leverage duck-typing features of their underlying language. In Django, a model is just a class, and many things are just queried via introspection. Many parts just query model_instance.pk. Additionally populating Model.meta and you even get yourself some deeper model introspection features. To me the true important part of ActiveRecord, ActiveModel and ActiveSupport is rather that you have a set of modules that you can readily include/extend into your fake models to inject complete model behavior, and that is something Django lacks.
You name the example of link helpers, and interestingly this is an example of the difference of philosophy between Rails and Django (see [0]). Django parts are coupled more loosely than Rails parts, a possible rationale being that creating coupling between two distant parts such as URLs and models could enforce constraints on each, thus reducing their potential to independently shine and coercing possible alternatives of each to the provided model. Another example: with Django you explicitly create a request object (whether directly constructed or encapsulated into a helper method) to be returned by the view function while Rails does magic for you in the controller.
Interestingly you bring the problem of forms and this is again an area where Rails and Django differ. Rails wants both form and data to be handled by a single model, whereas Django separates form models and data models. The rationale here is that they are two different problems and that they ought to be solved by two different components (yet they share a great deal of similarity, and code).
FWIW I worked extensively with both (although my current job is in a Ruby shop, I worked with Django at my previous job and since I'm more of a Python guy I keep myself up to date on that front too), and am in no way saying that one is better than the other. Choose what works for you.
[0] http://stackoverflow.com/questions/61451/does-django-have-ht...
I think this is incorrect. You can't offer features without implementations; The feature will never be completely agnostic of its implementation. When you get a really strong shift in the possible implementations (for example: websockets or even long polling, vs rpc) then the feature (for example: dynamic UI), if re-implemented, starts exposing very different semantics and secondary features.
To sum it up: if you implement a thousand ORMs based on SQL db's then they're all going to look the same, implement one thing based on a NoSQL database and you suddenly see how the "feature" of "storing data" suddenly becomes something different from what could be anticipated by the people who designed the original "feature" back in the SQL era.
Let's not lie to ourselves and pretend that features are some wondrous thing poised in thin air above their implementations.
1) Project starts out relatively agnostic and casts a very wide net
2) Features start to mature and while you are servicing one use case, you are somewhat unknowingly making your product unsuited to certain different future use cases that may or may not arise.
Thats just how design decisions work. Django has made design decisions to cater to a certain set of needs and they have obviously been quite successful. I don't even use Django but I can tell it doesn't "suck" just by how many people have told me it has fit their use cases quite well.
I actually wouldn't be surprised if X years down the road Flask becomes much less agnostic as its community consolidates and matures.
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.
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.
https://plus.google.com/112678702228711889851/posts/eVeouesv...
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!
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.
* Form * HttpResponse * All middleware * Template * Etc, it's all classes except if you write function based views
But it can be very difficult to do relatively simple things with Django sometimes, mostly in the admin pages. Admittedly, this is a pain point people bring on themselves by trying to do too much there, but it's a big red swollen example of how too much interleaving and complexity make it painful or impossible to reason about what's happening.
That said, I also chose to implement many of my admin changes at a higher level: templates which use jQuery, etc. and interact with the REST API for e.g. complex object creation are much easier than the crazy form / widget hacks I used to try.
It's just not constructive for the discussion, interesting as it may be.
It's frankly an awkward fit for loads of web applications. It seems to me (note: Django guy, not RoR guy) that the Rails stuff has adapted much better to applications that fall well outside of the blog/publishing sphere... but maybe that's a false impression.
I'm currently writing a control panel for libvirt and it's a pleasure to use Django, so many features mean I can concentrate on the problem at hand and not on reinventing the wheel.
No, they have a different idea of what a framework should do or not do. Doesn't mean they have some utopian idea just because it's not Django.
In practice, I think large frameworks are eventually pretty terrible. It's too easy to compromise your business needs in small ways because the framework offers you something close-enough. Whether those compromises come in the form of over-coupling (which they always do with these frameworks), or in other ways like compromised URL design, query performance, or authorization plumbing.
Great at first, but in my experience a project run long enough in one of these ecosystems tends to outgrow it.
Being faced from the beginning with more of a blank sheet of paper and open ecosystem of solutions to choose from (or build) tends to make you more aware of the trade-offs, and how well the solution you're implementing fits your business needs. Costs more up front, but you're less likely to grow a hate-tumor during years 3-6.
Case in point: OpenERP. Serious business software doing serious business things, so of course they can't use any of those other toy ORMs, they have to spend 5000 lines of code writing their own: http://bazaar.launchpad.net/~openerp/openobject-server/trunk...
Hey, it might not be so great, but at least they have tests for all of that code: http://bazaar.launchpad.net/~openerp/openobject-server/trunk...
Er...
I know of other projects in a similar state, but they're smaller teams or solo coders, so I don't know that they're quite as fair game for finger pointing...
My own observation is that bad codebases are the result of bad development practices regardless of framework. In my last job the code quality was so poor (and the management processes so broken) that whether they'd used Django, Flask or roll-your-own would not have made a whit of difference.
At this point I'd prefer to work on a well-managed, professionally coded project written in PHP than one written using <insert-python-framework-du-jour-here> run by idiot managers.
If you think you can do this better than the Django community, this can work out well but I'd say more often than not when I've heard about it people weren't actually able to spend enough time on this as they'd hoped and keep falling further and further behind Django and other frameworks.
I'm not sure where you work, but this is my experience from using 'wysiwyg' clipper & dbase software in the 80s to Delphi frameworks in the 90s to web frameworks. People think they are very different from the start and then (usually after a management change) they notice the same stuff happens everywhere.
With regards to frameworks. I find it hard to believe that none of them would work out in the long run. I wonder if you are under-estimating the cost involved from the developers to replace or create these frameworks from scratch. This also seems like a selection problem more than an inability of frameworks to meet any development need. I mean they do exist for a reason.
That said, most software products are pretty horrible. Many frameworks are equally bad. Does this mean you should custom build everything? Of course not, you company is not going to be able to afford the time it takes you to write your own ORM, your own web framework, your own logging library, etc... It is your job to make compromises that will allow your company to achieve its goals.
Each of those arrows from slide 25 on should have a little label: "Things that you have to write yourself in Flask."
Django is badass for what it is intended to do: be a kitchen sink. Flask is badass for what it is intended to do: be a platform for composable applications. If you ever need to reason about the internals of your web framework, you want the latter. If you don't, the former is great.
I'm not sure what that even means, but I suspect the thing that disproves it is "The last website I built was in Yesod.". And while it may be in some sense targeted to fill the Django space, at the present time (and certainly at the time I worked in it) it was more like Flask and a couple of things lightly tacked on.
No, my main point is that Django is what Django is, and while that may not be perfect, it isn't useless, it doesn't "suck", it just doesn't meet all needs any more than anything else does. Flask doesn't meet all needs either. Don't complain that water is tasteless when what you wanted was mustard. Being tasteless doesn't make the water suck, it just makes it water. Complaining about its watery nature is just silly.
If Django actually sucked I'd probably not have said anything, but it's more successful at actually bringing together all those things than most of its competition. (Though since there are roughly 1000 web frameworks out there I'm sure there's better things somewhere.)
"You sound institutionalized."
I'm not sure what that even means
mattdeboard is referring to Red's dialogue from The Shawshank Redemption: http://www.youtube.com/watch?v=TsiFanovOSIThis was a presentation for a room filled with Django developers that likely use it for just about everything.
The purpose of the talk isn't to bash Django, it was to introduce Django developers to some interesting concepts that are worth exploring and a tool that may suit their needs.
I won't slam Django, Django is good. Its most salient traits are its mindshare, liberality with features, big plugin ecosystem. And these traits were not all present from the beginning, when it was the Django developers who were reinventing wheels and going without features. Django's top traits are historically contingent. So in an alternate history, we might be talking about CherryPy having basically the same problems, because of the inherent pain of taking on so many features so quickly, then maintaining backward compatibility, etc.
Good framework or library code takes significantly longer to develop than similar functionality inside an app. When you add goals like trying to reduce boilerplate and coupling, it gets much harder and slower. It is totally valid to question why not just charge ahead with something easier to develop and get done more quickly. There is a real issue to think about here, it's not so clear cut.
It isn't as simple as saying "Flask is only nice because it has no features, anything with features is necessarily ugly." Both features and clean design take time and if you want both, even more time. But design is hard while features earn mindshare and dollars... if they work reliably, then who is complaining?
Now, at this point, Flask actually has a significant mindshare and plugin ecosystem of its own, so it is really inaccurate to say it has no features. And actually Flask does have a number of dependencies as well, with much of its implementation tucked away in Werkzeug (which is hardly a simple library).
It actually is what Flask does.
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.