I’d like to encourage everyone that uses Django in a commercial setting to speak to their company about donating to the DSF to continue getting timely bug, security, and feature releases.
Going to Python 3 is going to be the biggest annoyance yet.
The Python 3 update took longer and had a longer legacy of surprise breakages, but I don't ding Django for following the intended life cycle of Python.
I'm surprised you're surprised. Have you seen the size of the breaking changes documented with each release notes? We typically hit about 10 of these changes per release, sprinkled all over our code.
And those are just the intentional breaks. We find a lot of unintentional breakage too, and sometimes we accidentally use undocumented stuff which of course also isn't documented when it breaks. Each Django release has added an average of 32 commits per release for the past four releases just to deal with the version upgrade.
If documented stuff changes, Please report it (though that likely means testing against the alpha / beta versions (or just master). Keep Django honest.
If you find yourself using undocumented features, consider documenting them; that way they’re held to backward compatibility.
Also, follow the development of Django and comment on the intentional breaks if you think they’re not worth changing.
Disclaimer: Core dev now, though I had this attitude before that too.
I really don't want to be sucked into Django's drama:
I've encountered very little sympathy from Django developers. Everyone seems to have just accepted that it breaks often and it's totally my fault for not keeping up with the breaking changes. Everyone seems to think that Django breaking compatibility all over the place is good, proper, acceptable, and inevitable. Nothing is sacred, anything can break, and make sure you go through that list each release to see what you have to change in your code.
This makes me sad and frustrated.
I think it would help if you bring it up on the Django-developers mailing list, if you haven't yet. I think that would help raise awareness about the issue, and I hope it would lead to some policy changes.
If you're in Python 2 the bytes/str story is still mixed up, so API solidification happening in Django iteratively (in preparation for Django 2.0) will likely break a good amount of your code.
Inversely, we moved over to Py3 in the 1.7 days so we were spared some pain on that end.
Python3 upgrade is a task, agreed. But it actually gives good returns. The language is nicer to write in and we even saved some memory and CPU on the same load after the upgrade. So highly recommended.
How has Python 3 performed since then?
"Ding: We did not have performance gain expectations for Python 3 right out of the box.
So it was a pleasant surprise to see 12 percent CPU savings (on uswgi/Django) and 30 percent memory savings (on celery).
It’s only been four months since rollout, we don’t expect to see constant 10 percent performance improvement, but that was a very promising start."
Do you have decent test coverage and use tox to run your tests against multiple versions of Django?
If not I can recommend this approach from experience.
On the plus side the original authors managed to avoid using Django features so that makes it a bit easier. Someone actually wrote their own ORM in the process
I really like the new URL syntax they introduced. I'd been relying on 3rd party libraries like Django REST for years at this point, because the raw regex URL syntax was always annoying and verbose. The new syntax looks well executed.
I've been working with 1.11 and Python 3, so I'm looking forward to upgrading soon.
This is where people fear the “magic” of things like pluralization of models to table name and introspection... but it’s all just code! You can read it and look at it and understand it. No magic here. Just convenience and a smaller mental model as an end developer.
Also... resources as a first clsss citizen is the biggest reason and the reason it defeats Django for this use case. You define ‘resources’ in your routing layer instead of just routes that map to a function. This allows you represent multiple crud actions with a single controller and even nest them, all with a few lines of code. Then you get access control for free on your sub resource, knowing you’ve already passed the parent checks and have that context.
In this case, my Photos controller will already know who the user is (and if they can view these photos) based on work that the parent did. It’s single responsibility principle. You can even have a top level photos resource devoid of the user context and support both cases with minimal effort.
Yes, you can do these things in Django. But it’s not designed to make these things composable and seamless. I’d argue it’s not REST-friendly. Don’t even get me started on Django Rest Framework which is a massive beast in and of itself.
You get all of that out if the box on Rails. You can stand up extremely robust and ergonomic API’s with so little code you’ll feel like your cheating.
I should probably write a blog post.
Though, when it comes to prototyping, I think Rails is a much more convenient option. In Rails I can launch a working CRUD app with authentication in 10 minutes, literally. In Django I have to manually create directory structure, manually specify each route mapping, create and program controllers (views), etc. Django doesn't even have a built-in authentication templates, only controllers (views), so I end up writing this boilerplate over and over again. The other thing is that the authentication requires a username and password, which feels kind of clumsy, when every other authentication relies on email and it is not very trivial to modify that (built-in admin dashboard relies on built-in authentication for example).
Someone still had to create that database with those tables in it. It didn't magically pop out of the aether. Your complaint, then, is not "you must define every bit", but with where you do it, since you have to define things no matter what.
And if you have an existing database you'd like to use with Django, 'manage.py inspectdb' will reverse-engineer a set of model definitions from it.
If you have an existing database, sure, Rails is preferred. If you're starting from scratch, the Django definitions can create the tables for you. If you do have existing tables though, you can use inspectDB to have Django create the models for you.
My Rails projects have always been the ones that felt the most done on their initial release. That extra time not typing and configuring goes into caching, validation, UX, and making nice solutions to project specific problems that fit nicely and don't become pain points as time goes on. All these things that can feel shortchanged in other projects get more of the polish they need sooner.
Ruby - Rails
PHP - Laravel
all nice choices
Elixir - Phoenix
I wish there was a complete Clojure - ???
Elixir itself is an excellent language that leveraged the strengths of the Erlang VM, and Phoenix is like a massively improved, blazing fast and reliable version of Rails.
It will be the logical successor to Rails. It already is.
That said, I use a good mix of Elixir+Phoenix and old-school cron launched Python utility scripts, and that works nicely. Anything that's difficult (probably because I am still a newb) in Elixir I can easily do out of band with a Python script.
But your point about difficult to hire experienced people is the reason for my reply. This is the mentality that is ruining IT and development. Yes, having someone with hands on experience in all of your tools is nice - a rare luxury in fact. But it's really not necessary. I would be quite happy to have someone that has willingly built something in Rails, Django, and Nodejs with an "Oh I can learn that" attitude. Especially if you come from a modern MVC framework, Phoenix itself is easy. Elixir is the part that requires some real effort, imo.
I personally find that Laravel is less heavy than Django which is way less heavy than RoR. I would never use RoR for small projects.
btw: what do you use for the database access? Slick, Quill, Doobie, ScalikeJDBC, Anorm, Squeryl, jOOQ, Relate, Activate or something else? There seem to be gazillions of sql libraries for scala (although the big three and most relevant are probably Slick, Quill and Doobie).
And what do you use for Authorization? Something custom build? If I look at Laravel there are quite a few maintained authorization libs with ~1000 stars on youtube (even more if we count unmaintained), for play there is not really much (deadbolt, play4j and t2v/play2-auth, I don't count Silhouette since the lib is mainly about authentication).
Rhetorical question by the way... just food for thought. There is a balance. I happen to love the convention rails imposes and the “magic” it offers. That being said, there isn’t anything about it that I consider wizardry or don’t understand. It’s just ruby.
Are you not talking about Java here? ;)
Clearer code makes it easier to reason and hence easier debugging. Correct me if I am wrong.
Also, it really depends on person to person on how they write the code. Django does not mean big boilerplate nor does Rails.
My main question was on performance. How do they stack up next to each other? Python3 with Django is really working well these days. You can also check out the performance improvement on Instagram because of it. https://thenewstack.io/instagram-makes-smooth-move-python-3/
Generate dynamic HTML on the server, that still works just fine. And codebase will be way simpler as you just generate HTML on page refresh. No need to fiddle with event listeners and DOM and AJAX or whatever.
Single page web apps are often wrong choice if you just need some UI other than some fancy dashboard. Let’s say you need an admin panel where you can do CRUD operations, that’s perfect for Django/Rails and would be much much more work as SPA.
My personal preference (for most use cases) is a combination. Some things are easier done in static templates but JS is needed to really bring a page to life IMOP.
Lately there is too much SP-appage around where there are simpler alternatives though, with that I'll agree. I guess it keeps people employed screwing around with webpack so there's that.
Yes. But for 90% of business UI cases, you have some sort of collection of pages (i.e. website = collection of pages not a single page with everything crammed into it) with navigation menu. You use the menu to navigate to different pages with HTML forms that submit POST data and do GET redirects.
Trying to cram an entire business logic into a single page is often detrimental, split it into multiple pages. Highly interactive apps that fit into a single page model is maybe 10% of use cases or less I have seen in my career last few years.
This is all just my opinion obviously but I just think SPAs are a fad that will hopefully go away.
About NGINX, is still needed in both cases IMO, for the API or the frontend server.
If it were me, I'd probably use something else before I tried to squeeze that much performance out of Python at this point to though. I hope library support catches up and it becomes more convenient, but I don't think a predominantly synchronous ecosystem has really successfully transitioned to async before.
If I had to choose a framework for a web API these days, I would go with something that is async from the ground up.
Because we are getting more and more CPU cores to utilize. I don't think this trend will stop soon. The software stack will have to adjust to this and it already does. The next generation of mainstream (highlevel)languages/frameworks will be those that are designed to easily utilize CPU cores. It may be more expensive for now, but it might pay out later and I think it's much more exciting. ;)
With 30 workers threads in Python Django, I should be able to make very good use of 6 CPUs even if the workers only run 20% of the time.
Like those: https://docs.djangoproject.com/en/2.0/ref/databases/#using-a...
They are, indeed, quite complex.
I'd agree with you for a very simple API (like a simple slack/irc bot), but for a CRUD, you'll need to write a LOT of boilerplate code with Flask
(1) Write your new endpoint.
(2) Proxy to it via your old one.
Or for a full re-write you might want to do things the other way.
(1) Wrap the whole old app with a skeleton of the new one - just proxying the endpoints for now.
(2) Start replacing the endpoints.
OR: (1) write your endpoint. (2) use something like apache's mod_rewrite to adapt endpoints.
If I were to use Flask, is there anything that I could not do but that Django could?
Suddenly it's not so simple.
That being said, if your app really is simple (single file, under 100 lines) flask is excellent.
The problem is that a lot of people writing Python web stacks don't know how to write Python at all, and no framework will save that shortcoming.
Flask is advertised as a micro framework. if you want to rebuild Django with it then sure you can, but I personally can't see why you'd want to.
Flask is, of course, more powerful than bottle, and has less batteries included than Django. Saying Flask is good for 100 LOC sites is terrible advice, no matter which way you try to slice it. It isn't. It's widely-used and well-maintained.
Don't get me wrong, I like Django as well.
Django is no different. Django falls apart spectacularly in the hands of people who can't program.
I'm using Flask, but building my apps with Python.
This simple/complex equation should be reversed IMHO. Want to throw together something quick? Go with Django, where everything you need is built-in. Want to build a big app? Go with Flask, and build your stack specific to your needs.
As a bonus, once you have built a complex app with your own abstractions/magic succesfully, it becomes faster for you to build new projects with your own framework than any other alternative.
There are tradeoffs of course: you give up the Django admin and a bunch of other things, at which point we might as well have used Flask. But our shop has a number of other "normal" pure-Django apps so it makes sense for us to use Django as a common base.
Awhile ago there was a book called "Lightweight Django" in which the authors showed how to use Django in a stripped-down Flask-like manner. Ultimately Django is just a big bag of parts that you can use or not use.
It's exactly the same situation: either you luck out, and someone already wrote all the conveniences and utilities and integrations with components for you exactly the way you want them with exactly the set of other components you wanted, or you do it yourself.
Also, you could make a similar argument about swapping major components into, say, Pyramid. Most of the alternatives people promote to Django are not really some paradise of trivially-swapped-but-tightly-integrated components. They just do exactly what Django does, with a different set of "use these or lose the integration" components chosen up-front for you.
But yes, with Flask (or similar frameworks/libraries), you need to do the integrations yourself with the components you want to use. Advantage of Flask in this regard is, you don't need to fight with Flask to make it happen. That's why I'm saying it's better suited for complex apps that you want to build with your own abstractions.
The real problem is the cargo cult thinking when it comes to frameworks, instead of doing a cost/benefit analysis and thinking about trade-offs.
Following statements like "Django for complex apps, Flask for 100 lines of apps" without researching the reasons behind probably will result in more problems in the future.
Really? So you got all the things you get in Django -- ORM, forms with validation, etc. etc. -- from "a few lines of code"?
Somehow I think that's not true.
If you're familiar with SQL, it may take some time to adapt to the Django ORM, which is really great but favors ease of use over power.
All in all, with Django you'll fight to override defaults and with Flask to enforce them.
I loved both enemies
No, but it might be simpler.
When I started doing webdev in Python I used Flask (it's so slim, they said) and I still like it, but if you have some kind of DB in the back and care about user management, Flask won't help you.
Most people then use sqlalchemy and specific extensions for Flask to handle the user and security stuff. Although this works, I would advise you to start with Django.
Django isn't particular bad at this (it has some escape hatches to allow you to e.g. write custom SQL), but it is overal still quite a big framework and it's certainly harder to bend to your will than Flask.
So, you need to know the extra things it gives you and figure out if they will be helpful for your website.
Loosely, Django is: routing + HTML request parameter handling + HTML rendering + templating + user sessions + lots of database read/write help, assuming simple CRUD access patterns.
Flask is: routing + HTML request parameter handling + HTML rendering. Then, if you want any of the other things, you go and find a library for them.
The time you save initially you'll later spend fighting the framework or debugging its internals.
Python's "explicit over implicit" scales a lot better, especially with large teams.
(personal opionion of someone maintaining production-critical Django and Rails applications)
The parent comment being flagged to death is enlightening on both counts. I also appreciate your telling me you'd comment and vote on a thread about a Django release even though you've never used it and aren't a developer. That's simply fascinating!
- The Django codesource is easier to read
- Maybe error messages are cleaner? (just a supposition.. I don't know)
Also, this will eventually allow type hinting in the future.
For web stuff, I'll probably be using a C# framework, or Wordpress with one of the JITs. Still, a lot of hard work has gone into Django 2.0 and I'll be keeping tabs on it, rooting for the team. It's not likely but not barring the idea of using Django again.
Maybe they’ve switched to c# lately and are using lack of py2 as a trigger to rewrite. Maybe going after the benefits of a compiled language. Maybe just wanting to use c# because it’s one of the best languages out there.
There are some python apps out there I’ve contributed to that I’d rather rewrite in a static type lang rather than migrate to py3. Others I’d move to py3 no problem.
The idea that anything of value has to be nationalized and assimilated by the framework is a misguided effort to prevent chaos in the ecosystem, but the end result of trying to maintain order in an emergent ecosystem is usually disaster.
I think the "it" in the sentence:
> DRF makes it almost impossible if used correctly.
> claim to make "REST APIs", but they fall so short in a lot of aspects
I can't wait to check it out more.
On a sidenote, I feel bad for the developers who have to migrate to Django 2.0.
Hopefully it's not too much work, I know a codebase review and full update can't be fun with the business managers and customers at your throat.
If your code was emitting deprecation warnings, then you have to fix them before upgrading, but this should be relatively rare and they shouldn't be that hard to fix.
If you're still on Python 2, then you have to either migrate to Python 3 or stay on Django 1.11 (which is an LTS release). 1.11 EOL is April 2020, which is the same time as Python 2's EOL, so you were going to have to migrate your codebase by then anyway.
That's an optimistic viewpoint.
If you need to upgrade from Python 2 to Python 3 it will likely be a fair amount of work.
In case it's useful, here's what I did to upgrade my blog (a pretty simple application, though one that's been around for a long time and survived a lot of different Django versions): https://github.com/simonw/simonwillisonblog/pull/10
Django only has one paid full-time maintainer to my knowledge (Tim Graham). So given the team's limited peoplepower Only the last two releases (+LTS releases) get security updates. This means that Django 1.10 (released 18 months ago) won't get updates, so if you use any new features you're on the upgrade treadmill.
Django itself is very good about offering clean upgrade paths. Very vocal about breakage, usually will not introduce breakage unless there's some good reasons to. Unfortunately third party libraries often take a while to update, so you can quickly find yourself overwhelmed with figuring out which deps are safe to upgrade and which aren't.
I try to be a good OSS citizen and send in compatibility fixes for libraries that fall behind, but maintenance can be hard when you're only really using about 25% of a library.
I wouldn't be comfortable with sticking to older Django LTS releases (there was still a lot of obvious improving to be had in the ORM and migrations in particular), but I think Django 2.0 is in an amazingly good place now. Sticking to this for a couple years would be fine for a lot of people.
It indeed does, but I don't agree that it is too limiting in that respect. A lot of Tim's time is spent curating, reviewing and merging PR's contributed by the community. It's far, far from a one-man band.
Not sure if that was what you are implying, but that's how I read it.
Garanty of compatibility between Django and ALL my external packages is a lot more valuable that a responsive admin panel and a new syntax for urls.
I would love "important" (yeah it's opiniated) packages move to the official Django repo (like Channels), to help reduce this risk when migrating.
It's actually surprising how often I can't find the compatibility information of a Django package.
I would love to see someone start on a combination of `pyup` and some "maintenance fee" for projects that are found in ones `requirements.txt`.
For a monthly fee you can make sure that at least someone is checking to see that your Django dependencies are being kept up to date as time moves forward. The pitch being "get an extra maintenance developer for a fraction of the cost".
Though, in theory, I don't think there's any actual difference in support having it under the Django _organization_.
Source: before we hired Tim, I was doing most of the releases.
If you don't receive warnings, your code will work fine on future 2.x releases.
Stability is very important too.
For me it comes down to one simple thing though: Migrations
Django has, far and away, the best migrations system I've used in a Python framework (although I won't claim to have used them all).
Compared to Alembic it's vastly superior also beats most jerry-rigged solutions.
Claps for the changelog, it's always a joy to read, I haven't really used Django in some years but could easily read and see the changes. The new URL formatting is a very good add-on, was always the thing that annoyed me the most.
Great work! I love Django and look forward to seeing how it continues to improve.
“Django 3.x requires Python 3.x”
“Ah, OK, so to use Python 2.x I should go back to Django 2.x?”
“No, Django 2.x requires Python 3.x. If you want to use Python 2.7 you should use Django 1.x.”
I think the real crux of the discussion around which framework is best is really about the relationship between the framework and the language it's based on.
Let's separate this from the Python world for a second and talk about the relationship between Objective-C and iOS. Knowing the former doesn't in any way imply that you know the latter. There's an incredibly host of things you have to know to write an iOS app in addition to knowing Obj-C. XCode, UIKit, all the different xKits there are. Which are basically magic, and the APIs you're referencing are not necessarily written in Obj-C.
It is even possible to be a competent iOS developer and not really know anything but the framework. No real understanding of Obj-C or Swift is required, let alone any guiding principle of how programming languages work or how computers work, or how computer science works.
That's not a dig against people who went to code camp or took an online course or just read a book. I'm someone who learned about stuff mainly by reading books. And that worked out fine for the first few years of my career. But there's a legitimate problem that you run into (I know first hand) about what you do when the framework breaks down or you encounter something unexpected.
Anyone can learn a framework relatively quickly. What do you do when the framework fails for some reason?
As someone who learned SQL and Python from the ground up--language-first--I love that Django exists. It's damn impressive, and only ever gets better. But I like Flask + SQLAlchemy better, and I like Pyramid + Stored Procedures best.
I would probably have a different attitude if I started with Frameworks first. And again, that's not a criticism. It's just a different approach. One way to get things done is to learn the fastest way to get things done, and in many cases that's quite possibly Django or Rails.
But both of those make me a little nuts when I dig into the internals. Magic isn't bad by definition. Good magic is when you can invoke a class you don't have to understand to use well. Bad magic is when you have to understand the internals of a class to work around it when it fails to meet your needs.
But I think we need some context about this when we talk about which framework reigns supreme. If you're taking a class and learning to write web apps for the first time with no other experience at all, Django is the bomb. You can spend an entire career as a Django developer and do well.
Just like you can spend an entire career as an iOS developer writing apps, do well, and never actually learn anything about programming. I think this is a wonderful development in our world of programming because it brings so much economic opportunity to such a large group of people who wouldn't otherwise have access to it.
I think it's safe to say that Django is creating jobs for people who wouldn't otherwise have them, and that's a good thing. My 98-year-old father and WW2 vet is starting to help me with a Django app just as a thing we can do together. And I don't have to teach him anything at all about anything except that framework.
It's a brilliant and beautiful framework, and I love it. But to me, it's a little bit more like iOS or RoR than it is a framework that's really ideal for people who started with bottom-up rather than top-down development.
I know what I need in a new project, and it isn't going to be all of that. And I know how to quickly integrate the boilerplate things I will need. That's what repos and plugins are for.
The short version of my response to everyone talking about different frameworks is this: we need them all. Bottle and Flask are great; Pyramid is great; Django is great.
What you are using them for is an important consideration, as is who you plan to have working on them.
Another solution not mentioned in the link is the `Subquery()` expressions added in Django 1.11. A lot of databases will optimise those just as well as the `SELECT ..., COUNT() FROM ..JOIN..` that you would write by hand.
I added support for filtered aggregates in this release, if you're annotating multiple counts this might be useful for you.
I am guessing it is one of the points where the ORM breaks down.. which the answer is "use rawSQL"