Here’s to another 20!
What I'm not a fan of, is the query DSL. Normally, the developer works to figure out how to express their problem with SQL; then the DB engine works to figure out how to map that SQL to the data it has on disk. Now Django adds another layer, which is completely unlike SQL, has its own unique pitfalls, etc; sometimes I find myself just dumping the raw SQL, working on that to get the result I wanted, then working that back to the DSL.
I think SQLAlchemy gets it right. The query language is a thin veil over SQL, and mapping to objects is an explicit and clear operation. What does feel clunky to me, is setup: SQLAlchemy expects you to bring your own glue; Django is vertically integrated.
Fortunately, I now have AI to write any Django queries for me.
I think there were also some technical details I liked better about Litestar where it was more explicit about things while FastAPI was more "opaque magic happening in the background", but to be honest I don't remember all of those.
We are jealous of some FastAPI features though, so it's possible we could migrate, as Litestar's mapping between domain models, database models and API models isn't as flexible as we'd like.
https://laravelpodcast.com/episodes/c7807d42/transcript (Search for “Paris” to find the relevant section)
https://github.com/j4mie/idiorm
https://github.com/j4mie/paris
Idiorm was started in early 2010 while I was still writing PHP professionally. I’d heard about Django from a talk @simonw gave at the FlashBrighton meet-up group in 2009 and immediately fell in love. Idiorm and Paris, although not direct attempts to duplicate Django’s ORM, came from frustration that such an elegant ORM and query builder didn’t exist in the PHP world.
So in a roundabout way, Laravel’s ORM was absolutely inspired by Django.
As a side note, I’m still doing Django 16 years later and love it more than ever.
Right. I love Python and Django but the "batteries included" claim seems like an anachronism.
Job queues, WebSockets/SSE, setter/modern form rendering, API framework, components, comprehensive CLI, frontend support etc are what the competition have better integrates and/or first party.
Django's request.GET and request.POST were directly influenced by $_GET and $_POST.
Django's template language included ideas from the Smarty PHP template language.
Anyway, thank you Simon :)
I've been using Jinja for my own projects for a few years because I wanted more expressive Python code in my templates! I think we didn't quite get the balance right for that in Django.
Well, yes I didn't mean Django from the start! I mean now.
https://docs.djangoproject.com/en/5.2/howto/custom-template-...
In fact if you look at the source there is a lot of async methods in the framework itself which just straight up calls sync_to_async e.g. caching. This doesn't matter as much as hopefully it will get added proper async eventually. But I think believing your requests wont block just because you're using async is a bit naive at this point in Django and the async implementation has been going for years.
Not to mention that the majority of third party libraries lack support for async so you'll probably have to write your own wrappers for e.g. middleware.
TBH personally I have yet to work on any professional async Python project (Django based or not) which did not have event loop pauses due to accidental blocking IO or CPU exhaustion.
I take your point fully though that a lot of Django's "async" methods are really using a thread pool. (True for much closed source async code as well!)
https://www.quora.com/What-is-the-history-of-the-Django-web-...
simonw co-created Django. It's a fact. You don't have to like it.
Jacob joined shortly before I left, then Adrian and Jacob turned Django from a closed-source newspaper CMS project into open source Django. I think they deserve way more credit for the framework than I do, they made it open source and were co-BDFLs for the next decade of development.
I'll still take the co-creator credit though, because Adrian and I designed, built and sometimes even pair-programmed the core of the framework - request/response objects, view functions, template system - together during my year at the LJW.
If you're interested in more details I told a bunch of the story in this talk: https://simonwillison.net/2025/Jul/13/django-birthday/ - and more in this Fireside Chat interview at PyCon AU: https://www.youtube.com/watch?v=1E_UqhFmJQs
I was write to be downvoted. Apologies for getting it wrong. I started using Django in 2008, and Simon's influence was very apparent at that point - my comment was not meant to belittle his contributions (I also follow him on Mastodon - big fan of his comments on HN and there).
I guess my memory was just wrong. I knew Jacob was hired after Adrian - but I thought they both started Django after Jacob joined, and Simon was an early intern. I had the ordering totally wrong.
Years later (2009), I got to do interesting work in a cutting edge machine learning lab due to the expertise I developed in Django -- I was accepted into the lab specifically to clean up the mess phd students had made trying to build a complex front end using Django's ORM with physically separate per-user MySQL database servers.
All the things that came after -- being the first full time employee at a machine learning spinout from the lab, getting acquired by a big company and scaling up sensor-driven ML in the real world, quitting to co-found an ML-centered VC fund, starting a (now 10 year old) AI company -- none of it would have happened without Django.
Also, how on Earth did the ML PhDs decide physically segregated databases for each user were a requirement?
And if you spend any time working with a group of PhDs, you'll be shocked at some of the harebrained schemes they come up with. Dumb people are dumb in simple ways. Smart people are dumb in genius ways.
The magic removal branch in 2006 was one such case (of API instability). I recall another case circa 2007(?) with a "new admin". But, importantly, pre-1.0 Django made no guarantees of API stability. Post-1.0 Django has had a pretty rock-solid reputation for stability and security.
> Also, how on Earth did the ML PhDs decide physically segregated databases for each user were a requirement?
I worked at several labs at top academic institutions, on everything from supercomputer MPI work for multi-agent sims to image pipelines for large weather simulations, and one thing I learned is that being a good coder is orthogonal to being a good researcher. In that particular case, the person who wrote the code made the assumption that the "customers" would not allow their sensor data to be stored alongside the data from other customers, and separate databases with separate passwords was the solution they came up with. Somehow they did not notice that the terrible ergonomics of this solution meant there was probably a better way. Once I ripped out MySQL in favor of Postgres (since it had proper security) and removed the cumbersome middleware layer performance improved by over 100x.
As a professional, apply to Masters/PhD programs in your area of interest, or be young and an expert in an obscure technology the lab uses. Some labs will hire out contract work, but can't pay well (hence be young). Other labs have grant money to bring in non-phd researchers, but to get the job you'll both have to be an expert in a required technology, and be able to contribute actively to the research area of the lab. At Yale, I did this, as second author on a conference paper showing novel methods for applying machine learning in multi-agent, sensor -driven environments. It justified my paycheck as a researcher while I spent the other half of my time fixing broken code for other researchers and writing the first version of the software for our lab spinout.
Edit: I just want to clarify that my experiences with this don't go past 2010, so YMMV. Getting old is tough sometimes, it still feels like almost yesterday.
didnt they hear about sqlite, great for this setup
What I did was change the architecture to support centralized aggregation in a large co-located Postgres server, implementing security to managed permissions for writers (sensor gateway) and readers (user accounts).
Eventually we had to write a pg backend similar in concept to timescaledb to handle the massive scale of sensor data we were ingesting...but that's another story entirely.
Every time I work with another framework I am reminded of how well Django has adhered to initial principles (batteries included) while adapting to changes with new technologies.
It has a great community behind it and for that to exist for so long is something remarkable. Other frameworks have advantages in some places. But for overall tooling I think it still is the best choice for anything large and complex yet not a bad choice for micro projects either.
I have to say thank you to Simon and the Django community as a whole.
Its a wonderful "batteries included" framework that has launched many successful projects, companies, and careers. Mine included.
And I'd be lying if I didnt say I still use pgadmin as my benchmark for evaluating admin panels in other ecosystems.
What you all created with Django is amazing.
We'd all be much further behind in tech without it.
Thanks absolute heaps.
There's still no framework in e.g. Go that comes anywhere close to matching Django. It's pragmatic, doesn't do too much meta-magic (I still don't "get" Rails), lets you strip away any layers you don't need, etc.
But the remaining 20%? Now you've dug yourself a hole with no recourse but a complete rewrite. It's time/money you would've otherwise spent anyway, but that sunken cost fallacy hits hard.
One framework which does not have this problem - or at least minimises the problem, is the Yii framework for PHP. A very nice and underrated framework
I don't think Go is an apt comparison. Its philosophy is to eschew traditional frameworks in favor of relying on the rich standard library as much as possible, and on small external libraries when needed. This does lead to a duplication of effort and bespoke mini-frameworks that only technically have a fraction of the features of a typical framework, but the end result is much simpler, more understandable and flexible. All in a highly performant language with a great ecosystem, packaging, and tooling <3
That said, Django is an amazing framework that has stood the test of time. Like many here, it was one of the projects that kickstarted my web development career. Kudos to the team and community, and here's to another 20! \o/
I am huge fan of Python and Django. I despise PHP with the force of a thousand suns but I give enormous credit to Laravel as a well-designed framework that makes life bearable when working with PHP.
Specifically for python vs django, most of the things I dont like are actually attributable to decisions by the python team, not necessarily Django.
But many of the things I do like are attributable to the Django team.
Writing a Django app is like writing Python, but it's more like writing Django.
everything just worked out of the box (compared to using java + spring and their endless xml config files), the orm was (and still is!) lovely compared to other solutions, and there were so many things included, that i never really had to go integration hell.
Who knows where I would be today if not for Django!
I learned Python more than 10 years ago, but later chose Rails to be my first web framework to learn, as I also wanted to learn more about Ruby, hence the question.
* I've always preferred Python over Ruby. Explicit imports, namespaces and the "only one way to do something" philosophy have felt more scalable. In general the language does not promote as much implicit magic
* Django reflects the same philosophy: more explicit definitions, a slight bit more configuration and ceremony but easier debuggability.
* The Django docs are, to me, some of the best there is in documenting the framework extensively but also teaching good practices. I've always felt the Ruby docs to be lacking in the latter department so you see more drift in Ruby projects on how to approach the same problems
* Django has felt much stable over the years. Migration between major versions is a breeze.
* The Python library ecosystem is much larger
* The Django admin and Rest Framework are some of the biggest timesavers I've seen. Rails has similar projects but they don't quite make it
Unless you're doing a GIS or project with scientific computing I would not let these factors go above personal preference, as Rails is still an excellent framework.
Lot of the places I see that use Rails now has a separate codebase for their Python work that has to be accessed via separate querying versus just using the Django ORM.
For most cases I would recommend Django to be the main framework for startups. But if you don’t intend to do any ML/AI and only need a defined set of libraries and you are a one man shop then Rails dev speed is so fast.
Django, however, is wonderful for internal tooling, or anything where you need to plug in Python libraries. GIS is a clear win for Django, as well as custom BI work or data analytics
Can you share more here? Would you go the route of django templates for internal tooling?
But, to help those wondering about RnR vs Django for dealing with GIS data, the answer is the python ecosystem is just larger for dealing with GIS data. There are more libraries like fiona, shapely, gdal examples, etc. Django ORM supports all of the PostGIS functions, geos and ogr object helpers.
Rails does not have an alternative for PolygonField, Raster support, or geometry field queries like filter(geom__intersects=area)
Neither Python nor Ruby are my main languages. I used to do a lot of Java and the last eight years I'm using Kotlin mostly. But I've done a lot of freelance and consulting projects as well where I'm happy to use whatever people are using there. I did some pyton and typescript+react recently. I've dabbled with a few Go and Scala projects even. And I'll grudgingly admit to having touched some Php even.
So here's my view:
For me, Django is slightly better than Rails because the people seem to prioritize it just being rock solid, stable, and simple. Python isn't the best, or most elegant at anything it does IMHO. But it's always simple and rock solid and I love it for that. That's what makes it a popular choice for non computer scientists working with data, people in university doing whatever, etc. Ruby was always the more esotheric choice. Lots of people obsessing about meta programming, programming esthetics, and changing their mind about how stuff should be done every 3 months. I found rails to be a bit limited and convoluted. Django and rails do similar things in the end.
The last time I did python, I picked Fastapi and ignored Django. Ruby is fine as a language but it seems to have gone out of fashion a bit. The last time I used it I was using Sinatra, not Rails.
I just prefer light weight frameworks. And I'm a bit opinionated on being able to use the full power of SQL and not having to proxy everything I do through some straight jacket ORM framework that does a lot of magical things in some mediocre way. I can create a table myself and mapping rows to objects isn't rocket science. And I'll write and optimize my queries myself. It's not that hard, and it's not consuming a lot of my time generally. So, the value of optimizing that time is not very high too me. The value of changing and optimizing it when I need to is. And so is the value of just doing it right the first time. And LLMs allow me to generate a lot of the boiler plate stuff (because it is so easy and straighforward). And I'm pretty good at abstracting and encapsulating that. ORMs don't really solve a problem I have.
In the same way server side model view controller (rendering HTML and serving it to the browser on every request) went out of fashion ages ago. Most web and mobile apps use APIs instead. And while server side rendering still is a thing these days, I don't really see a big need for that. It's an optimization. And not one I find I need a lot.
And since server side MVC and ORM are the main point of using Rails or Django, I don't really use either a lot these days.
But I still learn Javascript lol
I celebrated the 20th birthday yesterday by writing up an annotated transcript of my talk from the 10th - it tells Django's origin story: https://simonwillison.net/2025/Jul/13/django-birthday/
The Documentation as Empathy talk is one that I still think of often. It was fun to hang out with those guys after too. Lovely folk.
I've only worked with Express js as an alternative and I just love how Django handles lots of things for you and let's you focus on the core logic.
I was still at uni (2008) when I got my first PHP job. I've shown Django to my boss. He's never started another PHP project since.
Django is now older than I was when I first used it. To another 20 years.
The drift from a simple Flask to monstrosity Flasknjo was so natural that I suspect it happens to a lot of people.
It's like saying Django+DRF is a monstrosity compared to FastAPI/Litestar.
It wasn't long before newforms became a thing, and the 1.0 release, lots of cool database features, migrations (I remember debating South vs. Nashvegas at work), class-based views (amazing!), Postgres-specific features (built-in JSONField, finally!), Py3k support, ASGI... It's been a long, cool, productive road.
I was at the first DjangoCon in 2008 (leaving my wife at home with our two month old!), and giving a conference talk for the first time a decade later at DjangoCon 2018.
I owe my career to Django. It has been my framework of choice for projects large and small, and I've always felt solid in that decision -- thanks in no small part to the community.
HBD Django! <3
It's also somehow wound up being a north star of sorts when I find myself needing to reimplement behavior in other web stacks; I usually just go read how Django has done it, then adjust as necessary.
Hell of a run, here's to the next 20.
The coolest tagline ever.
- 25.6% funded
- $76,707 donated
:(
If we want innovation, transparency, and community-driven development to thrive, we have to step up — whether it’s donating, spreading the word, or helping out however we can.
Thanks to the creators, contributors, community, and maintainers.
I'm more of a Rails and Phoenix guy myself, but I have a lot of respect for this project. Never worked super deep with Django, but have worked with Flask and Tornado in the past.
Django is pragmatic, secure, and unbelievably stable. It's the framework you choose when you want to build a real business, not just chase the latest trend. It has powered some of the biggest sites on the web, and it's still the best choice for a huge number of projects.
Here's to 20 more years.
Source: me, I was programming in Zope 20 years ago (mostly hated it, although there were lots of interesting things in at a conceptual level), switched jobs at the beginning of 2006 and thanks to the new boss I got to use Django since February of 2006 (I think I still have a 0.96 version installed somewhere on an old instance, still does its thing).
Django and its contemporaries, like TurboGears and Pylons, were a breath of fresh air.
Certainly the release of Rails — and, more importantly, the questions in the Python community about what _our_ web dev story would be — inspired us to extract the framework from the rest of our code and release it. And over the years we’ve taken some inspiration from Rails (as well as anywhere else we see good ideas). The biggest one probably being the basic ethos that web development should be easy — the focus on what we now call “Developer Experience” is the best thing Rails gave the world, I think.
Cannot wait for the async and bg work interface!
Happy birthday Django you cutie
Back in the day, when I was first picking up on frameworks, I saw Django and TurboGears. A friend of mine went with Django while I went with TG. I don't really know what the status of TG is anymore but back then, I thought SQLObject, Mochikit etc. were awesome. I think I took the wrong fork in the road then.
I once attended a "web" panel at PyCon India where there was a discussion between proponents of various frameworks. The Django guy had a nice quote - "I don't know what the standard Python web framework of Python will look like in another 20 years but I'm quite sure that it will be called Django". His point was about the longevity of the project and it's ability to adapt.
Otherwise it's a fantastic framework that's extremely flexible and a joy to work with most of the time. Due to its longevity, it has such a rich ecosystem that's enviable and only mirrored by the likes of rails.
It's a good practice anyways I feel, as the application grows you don't want different "apps" to know too much about models in other apps.
But even with this flow, in my selector layer I still have to do "# type: ignore" any time I've used an annotation. Especially due to python's lacking lambdas, when I map data from a queryset it often has to be a properly defined function, but then whatever annotation django-stubs managed to apply is lost anyways.
Congrats team! Glad to see it's still thriving and a great option to pick up for beginners.
5.2 release was recently discussed here on HN: https://news.ycombinator.com/item?id=43556656
I have moved on to other things since, but I miss it's simplicity and the general "it just works" aspect of the framework.
Thank you to all the contributors!
Django's docs can't be praised enough, they've always been the gold standard that I aspire to, taking a similar approach to documenting my own stuff seriously leveled me up, and great docs written for humans by humans stand out even more amongst the painlessly effortlessly generated slop of the day that's painful and effortful to read.
Template inheritance was so elegant and simple compared to the Java and PHP I was professionally and personally using at the time, but 20 years later and after having used Hono, one thing I'd love to see in Django is... JSX in Python! Imagine:
def Layout(title: str, children):
return (
<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
{children}
</body>
</html>
)
def message_list_view(request):
messages = ['Good Morning', 'Good Evening', 'Good Night']
return render(request,
<Layout title="Messages">
<ul>
{[<li>{message}</li> for message in messages]}
</ul>
</Layout>
)Django Cotton [1] scratched my itch fully. Very composable. Being able to pass HTML to components (E.g. you create a modal which takes a content slot) removed so many of the warts I felt using the standard Django templating.
It's not JSX, but it plays well with Django and makes it feel like I can create a real design system of components without a ton of JINJA.
Before I knew it I was helping organize the user group including our weekly coffee shop meetups in addition to the monthly lecture gatherings. There were a lot of local startups (including some very well known businesses and non-profits today) very actively collaborating on these tools. Django was really evolving the way a lot of companies used software and automation.
It wasn't only the engineering, the community ethos of Django both at the local and international scale (and the Python community as a whole) really made it possible to branch out and accelerate my personal software engineering journey.
I honestly found it to be the absolute worst Python framework I've ever worked with. I found it so hard to intuitively write code for it because it just does stuff for you in the background and you can't always see the execution order of code, especially when leveraging that default dashboard feature. I lasted 11 months in a role that used Django exclusively. I'm happy for people that built a career with it, but it just blows my mind people aren't more critical of it. Not that they necessarily need to be though.
* I think Django is an amazing piece of software, developed by a lot of clever, brilliant people.
* I don’t want to use Django.
I think Django is unmatched for building a Django app. That is, if you want to connect to a relational DB, make CRUD queries with its OR , and spit out the results in the exact HTML or JSON it supports, you’re going to have a great time. If you want to hit non-relational backends (including APIs), form your own outputs, or reuse the SQLAlchemy models you built for another part of the project, you’re entering a world of pain. Mark it zero and move on. Turns out most of my stuff is doing non-Django patterns. But if that were different, if I were building a traditional website on top of PostgreSQL and starting with a blank slate, sure, it’d be high on my list of options.
The one thing that still bugs me is that you have to wire everything together manually. But other than that, much better than most.
Alas, that tends to be the majority of my experience with Django. Using it for one-off personal projects and quietly wishing for the current new shiny JavaScript thing to go away. It still feels like home, but most of my time is somewhere else.
spapas82•6mo ago
Django has a lot of beloved features but I think one of the most important is it's stability through the years: I actually have production apps that started on Django 1.4 and python 2.6 and now are updated and with with Django 5 and python 3.13.
All this without too much effort on my side or paying companies to support my projects.
So thank you Django people for the hard work!