Completely replacing the template system with Jinja is silly (no idea if this is what they did) since it significantly reduces the value of the Django ecosystem. Far better it to use jinja for your work, but leave the Django templates for Django and all the other apps you integrate to use. I do with Django would reduce their stance on no expressions in the templates. Sometimes it saves a lot of work to just be able to call a function or add two numbers together without needing to build a filter or tag every time.
I've been happy with django-jinja[1] for that purpose. It replaces the context processors so it will load jinja templates if they have a .jinja extension and Django if they are .html. It also includes the django filters in jinja-land.
The ORM is more problematic. I just started a project a couple months ago and thought a lot about ditching the default ORM in favor of SqlAlchemy. I decided not to, for the reason of expedience and, as the TFA mentions, it already leaks. So, I stuck with the Django ORM and will drop to SQL directly if need be (need being defined by the ORM making the code confusing or there being performance hotspots).
There are still a lot of Django apps that work fine in this scenario. Plus I don't think the slides imply that they are just blindly replacing ORM calls with raw SQL, just that they have profiled and replaced the hot spots.
Also Flask is a micro-framework and Django is a full-stack framework. Flask can be used as the backbone of a full-stack framework but figuring out a good project structure and finding out what third-party apps to use can be daunting for a person without Flask experience. If you really want to get people to switch, package up a Flask-based framework with the features of Django.
Middlewares, context processors, forms, (class based) views, and tons of third party applications.
The CTO of a startup where some friends are working thought the same you did, and 2 years ago rewrote everything to Flask. Now they're going back to Django.
"what advantage does Django provide at this point in this project anymore?"
Documentation. I use Django but without any ORM and with Jinja2, so it's basically just Flask but with more stack overflow threads and more third-party software.
Is there any actual advantage that I would be getting by using Flask instead?
In addition to what everyone else has mentioned, the amount of libraries written for Django is staggering. You almost never need to roll your own app -- someone has already done it!
It has an entire ecosystem and tool chain to sort building websites/webapps. When I used to use Flask, before moving to Django, I found myself essentially creating a whole bunch of stuff that Django already has, and is better written.
To throw a completely different wrench into the mix, I mostly just use Django to provide an API anymore, and for session handling.
I love and use Django, and have built large projects where I haven't really run into any limitations with it[1], but for the most part, nowadays my workflow is to pip install django, south, tastypie, then load in a template with Backbone and Marionette, then get to town.
Templates are either Mustache or Underscore, depending.
[1] - Yeah, it could be faster, but if you have a large, confusing database schema that you inherited, the Django ORM is great for getting things stood up, and then just tune the queries after the fact. It's still a huge timesaver vs. writing every query by hand.
Don't use just one ORM and then declare "ORM's are stupid". The "object = None" / "object_id = None" issue illustrated here is certainly not a mistake every ORM makes.
The SQL generated appears correct, unless the underlying database can guarantee that all foreign key constraints are met. That is, I consider this a failure of the user of the ORM to appreciate that the two invocations of filter are not identical.
In the former case, the query is verifying that the object_id field cannot be used to find a foreign object--regardless of the value of object_id. This is exactly what it is asked to do.
In the latter case, the query is simply verifying that object_id is NULL, which is exactly what it's asked to do.
Obviously there are subtleties to things that may not be apparent, but his example makes sense to me and so does the SQL queries that are generated. The first query is operating at the "object level" and the second is operating at the "attribute level".
The first is retrieving the object and checking if it exists, and the second is just checking the parent's foreign key. Not sure that they are really the same query, if you have unenforced foreign keys.
This is not "dumb", this is analogous to checking if a pointer is null or that the contents of the pointer are null (which is a distinction that some people want to make).
I think it's more of a case of the developer not having read the ORM documentation; this is a very newbie mistake (although very understandable, true).
Now obviously, some people would complain that it doesn't make sense to do the extra join, but then people would be complaining about magical or exceptional behavior. ORM behavior is very predictable about which fields are being queried
I was expecting this slidedeck to be a bit more focused on defying Spolsky, and whether or not that was a good decision.
FWIW, I've never bought into Spolsky's vision that re-writing code is poor strategy. Steve Jobs never thought twice about ripping something apart and starting over. If anything, code re-write can be an advantageous position -- you often have a greater understanding of the problems you're intending to solve. When well-executed, it can take the form of heavy refactoring, even when switching languages/platforms.
I found I could follow along with the slides, though some of the icons and messages around third-party tools were lost on me. I'd definitely appreciate a video.
Edit: 9 minutes ago, Nick posted to Twitter: "we have the recording - just need the sound cleaned up. Expect it early next week ;)"
could this performance improvement back-fire if you end up with a security issue?
I'm not saying that it definitely would. If you know what you're doing / trust your data sources or sanitize them elsewhere, you should be fine. I'd be careful turning off such a feature completely though...
Of course. This is merely a tradeoff between performance and developer time. 99% of projects will never have HTML autoescaping as a performance pain point. Then again, you're going to need tens of hours to review all templates to make sure you're escaping everything. If your hardware budget is greated than what it costs to audit the code, it's the proper decision.
I don't think Spolsky's argument applies to startups... His argument basically boils down to "You think the code in front of you is a mess, but the reality is you're just having trouble reading somebody else's code which is probably good enough". But what if you wrote the code yourself? In that case, it's probably just a mess.
Iconfinder. They are profitable? They have business requirements? Joel wrote about the problems of a rewrite when you need to earn money, implement money making features, heavy competition while at the same time maintaining two plattform where one is a moving target. I don't think Iconfinder fits in any of these constraints.
Did someone understand the last slides about the differences between transactions in tasks with and without celery ? I'm using celery, and i have been using django in the past, and I really didn't get the point.
He's trying to avoid the situation where you enqueue a background job inside a transaction and the worker gets started on that job before the transaction is committed. If the job needs to hit the database for any reason your likely to get errors as the new data hasn't been committed yet.
It looks like the work around he used is to cache the job queue locally and only flush it to the real job queue after the database commit, so your guaranteed whatever data may be needed for the job has been committed to the database.
Basically if you modify data in a transaction, add a task to the queue that relies on that data, and the worker pulls the task off the queue BEFORE the transaction is committed, then the task tries to access data that doesn't exist in the database yet.
The real issue with ORMs isn't the ORM itself, but over reliance on the ORM to do everything the right way and not validating the ORM is doing things the right way. ORMs are also often heavily leaned on by people who don't understand SQL and relational databases well enough and just want a data dumping ground (would have been better off with a document database).
But, if properly validated, and knowing when to NOT use the ORM, a good ORM can help you get a lot of work done very efficiently. But I've also seen improperly used ORMs turn into MASSIVE time sinks where devs spends days just configuring the stupid thing (hello Hibernate/nhibernate).
I guess his point is that they sometimes create huge ugly and inefficient SQL queries. (Reminds me of the 90s sentiment of C compilers creating ugly assembly.)
If you know SQL, they're often frustrating. You know what you want to do, but there's some ridiculous arcane approach to get those results via the ORM. If you can do it at all.
ORMs make it easy to do things like run queries inside a loop without realizing it. I worked on a site where the front page ran something like 200 queries every time it was accessed thanks to ORM magic.
ORM can abstract DB/SQL for you, but if you really ignore DB/SQL, then it can happily make some queries an order (or two ) of magnitude slower than they should be.
So, you must always think in explicit SQL-query-terms anyway; and then it's just a balance for ease of coding - does the ease of ORM syntactic sugar outweigh the effort for you to double-check if any ORM-built queries don't accidentally do something stupidly slow.
[+] [-] nnq|13 years ago|reply
...really, what advantage does Django provide at this point in this project anymore?
[+] [-] SoftwareMaven|13 years ago|reply
I've been happy with django-jinja[1] for that purpose. It replaces the context processors so it will load jinja templates if they have a .jinja extension and Django if they are .html. It also includes the django filters in jinja-land.
The ORM is more problematic. I just started a project a couple months ago and thought a lot about ditching the default ORM in favor of SqlAlchemy. I decided not to, for the reason of expedience and, as the TFA mentions, it already leaks. So, I stuck with the Django ORM and will drop to SQL directly if need be (need being defined by the ORM making the code confusing or there being performance hotspots).
1. https://github.com/niwibe/django-jinja
[+] [-] megaman821|13 years ago|reply
Also Flask is a micro-framework and Django is a full-stack framework. Flask can be used as the backbone of a full-stack framework but figuring out a good project structure and finding out what third-party apps to use can be daunting for a person without Flask experience. If you really want to get people to switch, package up a Flask-based framework with the features of Django.
[+] [-] pyriku|13 years ago|reply
The CTO of a startup where some friends are working thought the same you did, and 2 years ago rewrote everything to Flask. Now they're going back to Django.
Django is much more that an ORM and templates.
[+] [-] Alex3917|13 years ago|reply
Documentation. I use Django but without any ORM and with Jinja2, so it's basically just Flask but with more stack overflow threads and more third-party software.
Is there any actual advantage that I would be getting by using Flask instead?
[+] [-] andybak|13 years ago|reply
[+] [-] naithemilkman|13 years ago|reply
Also, geodjango.
[+] [-] antihero|13 years ago|reply
[+] [-] bmelton|13 years ago|reply
I love and use Django, and have built large projects where I haven't really run into any limitations with it[1], but for the most part, nowadays my workflow is to pip install django, south, tastypie, then load in a template with Backbone and Marionette, then get to town.
Templates are either Mustache or Underscore, depending.
[1] - Yeah, it could be faster, but if you have a large, confusing database schema that you inherited, the Django ORM is great for getting things stood up, and then just tune the queries after the fact. It's still a huge timesaver vs. writing every query by hand.
[+] [-] zzzeek|13 years ago|reply
[+] [-] k4st|13 years ago|reply
In the former case, the query is verifying that the object_id field cannot be used to find a foreign object--regardless of the value of object_id. This is exactly what it is asked to do.
In the latter case, the query is simply verifying that object_id is NULL, which is exactly what it's asked to do.
[+] [-] tmarthal|13 years ago|reply
The first is retrieving the object and checking if it exists, and the second is just checking the parent's foreign key. Not sure that they are really the same query, if you have unenforced foreign keys.
This is not "dumb", this is analogous to checking if a pointer is null or that the contents of the pointer are null (which is a distinction that some people want to make).
[+] [-] Aqueous|13 years ago|reply
[+] [-] InclinedPlane|13 years ago|reply
[+] [-] avenger123|13 years ago|reply
Using an ORM should not exclude also using direct SQL. It should be both.
I believe this brings the best combination. Anytime there is major complexity just drop to normal SQL.
The best of both.
[+] [-] Daishiman|13 years ago|reply
Now obviously, some people would complain that it doesn't make sense to do the extra join, but then people would be complaining about magical or exceptional behavior. ORM behavior is very predictable about which fields are being queried
[+] [-] JshWright|13 years ago|reply
filter(object__isnull=True)
https://docs.djangoproject.com/en/dev/ref/models/querysets/#...
[+] [-] macspoofing|13 years ago|reply
[+] [-] jroseattle|13 years ago|reply
FWIW, I've never bought into Spolsky's vision that re-writing code is poor strategy. Steve Jobs never thought twice about ripping something apart and starting over. If anything, code re-write can be an advantageous position -- you often have a greater understanding of the problems you're intending to solve. When well-executed, it can take the form of heavy refactoring, even when switching languages/platforms.
[+] [-] lstamour|13 years ago|reply
Edit: 9 minutes ago, Nick posted to Twitter: "we have the recording - just need the sound cleaned up. Expect it early next week ;)"
[+] [-] lstamour|13 years ago|reply
[+] [-] emperorcezar|13 years ago|reply
[+] [-] unknown|13 years ago|reply
[deleted]
[+] [-] rattray|13 years ago|reply
[+] [-] gingerlime|13 years ago|reply
could this performance improvement back-fire if you end up with a security issue?
I'm not saying that it definitely would. If you know what you're doing / trust your data sources or sanitize them elsewhere, you should be fine. I'd be careful turning off such a feature completely though...
[+] [-] Daishiman|13 years ago|reply
[+] [-] tachion|13 years ago|reply
[+] [-] iconfinder|13 years ago|reply
[+] [-] level09|13 years ago|reply
http://jinja.pocoo.org/ https://www.getsentry.com/welcome/ http://graphite.wikidot.com/start https://opbeat.com/
is there a way though to use/test opbeat ?
[+] [-] iconfinder|13 years ago|reply
[+] [-] hasenj|13 years ago|reply
http://lucumr.pocoo.org/2011/7/19/sqlachemy-and-you/
It gives you more control and requires you to be more explicit about your queries and relationships.
[+] [-] speg|13 years ago|reply
[+] [-] claudiusd|13 years ago|reply
[+] [-] scott_meade|13 years ago|reply
[+] [-] Uchikoma|13 years ago|reply
[+] [-] iconfinder|13 years ago|reply
[+] [-] bsaul|13 years ago|reply
[+] [-] mbell|13 years ago|reply
It looks like the work around he used is to cache the job queue locally and only flush it to the real job queue after the database commit, so your guaranteed whatever data may be needed for the job has been committed to the database.
[+] [-] ashchristopher|13 years ago|reply
[+] [-] spitfire|13 years ago|reply
[+] [-] dmishe|13 years ago|reply
[+] [-] Uchikoma|13 years ago|reply
[+] [-] beambot|13 years ago|reply
[+] [-] lstamour|13 years ago|reply
[deleted]
[+] [-] Kiro|13 years ago|reply
[+] [-] cwbrandsma|13 years ago|reply
But, if properly validated, and knowing when to NOT use the ORM, a good ORM can help you get a lot of work done very efficiently. But I've also seen improperly used ORMs turn into MASSIVE time sinks where devs spends days just configuring the stupid thing (hello Hibernate/nhibernate).
[+] [-] kybernetyk|13 years ago|reply
[+] [-] mattchew|13 years ago|reply
ORMs make it easy to do things like run queries inside a loop without realizing it. I worked on a site where the front page ran something like 200 queries every time it was accessed thanks to ORM magic.
[+] [-] PeterisP|13 years ago|reply
ORM can abstract DB/SQL for you, but if you really ignore DB/SQL, then it can happily make some queries an order (or two ) of magnitude slower than they should be.
So, you must always think in explicit SQL-query-terms anyway; and then it's just a balance for ease of coding - does the ease of ORM syntactic sugar outweigh the effort for you to double-check if any ORM-built queries don't accidentally do something stupidly slow.
[+] [-] macspoofing|13 years ago|reply