This is great and showcases Django's talent for basic CRUD apps with handy admin interfaces.
One catch: I like to deploy static sites to GitHub Pages. It turns out the Django ecosystem has an answer for that in the form of Django Distill [1]. Distill adds a new management command that generates static content by repeatedly invoking your views.
I've used Distill to build quite a few static sites. It's great to be able to deploy to Pages but use Django's admin UI locally. Typically, for these sites, I check in my 'production' SQLite database directly to my git repo.
(Combine this pattern with GitHub actions and you can do a lot with a little. For instance, here's a toy I built to summarize upcoming Seattle city council meetings [2].)
Simon Willison calls it the “baked data pattern” — where a read-only copy of your data is checked into your repo alongside your code. [1]
(And, just to tie the threads together, that’s the same Simon who wrote the OP we’re all commenting on, and who is also the co-creator of Django and more recently of the very handy Datasette!)
I had the opposite opinion. If you were trying to convert Rails, Laravel or CakePHP users, this would just convince them that Django was more manual and involved than those frameworks. It would be better to utilize extensions like `scaffolding` to give a more equivalent workflow. It does demonstrate general MVC benefits and architecture, however.
I was recently looking for a static site generator for a local relay race I help organize and django-distill was the top of my list. I ended up writing my own SSG because I had very little HTML that actually had to be generated on the site. But might check out django-distill in the future if you found it worth learning.
Can you think of a complicated app that utilizes Django to its fullest extent? I'm trying to get a better view of what Django is capable of and I find it's helpful to see both the simplest example possible and the most complicated example possible. "Design for the extremes" as Don Norman would say.
Instagram's backend is a Django monolith "with several million lines of code and a few thousand Django endpoints" as of 2019, and the same architecture was used for Threads! They now run Django on a JIT-enabled fork of CPython, and leverage a ton of internal tooling for static analysis and strong typing.
Django is also excellent for e-commerce with projects like https://github.com/saleor/saleor - or you can roll your own e-commerce system quite easily, which we've done at my travel startup.
23andMe is also a Django app, at least the logged in site[0] and the API[1]. The API actually started off with Django 0.96. I had the distinct pleasure(?) of upgrading it to Django 3.
I generally try not to publicly link my HN activity to my IRL identity, but my email's in my bio if you have any specific inquiries!
To the larger point about Django and e-commerce, though, I'll share that we do a large volume of complex transactions where multiple funds flows for different parties need to be coordinated, so it's been vital to be able to have a dynamic data model to track the payables/receivables lifecycle of a given booking and add overrides/configurability to handle unique situations as they come along. Django's been a perfect match for that, the framework source code is very approachable (IMO much less "magical" than Rails in this regard while having the same level of expressivity and shorthand), and since it's Python, it works extremely well with data science tooling as well.
The wagtail CMS would be a good example of more complex systems built on top of Django. https://wagtail.org/
One of the many more complex sites we've used it to build is https://www.business-humanrights.org/en/ which tracks over 10k companies, 100k+ articles in 15 or so languages. We've also built internal dashboards, live updating forums, donations platforms and so on. Another interesting one might be https://www.achurchnearyou.com/ which is used by the church of England to provide "mini sites" for all their congregations around England, so several thousand church administrators use that every week.
I've been involved with several enterprise applications based off of Django - leveraging signals, custom models, tasks, etc. to power insurtech and fintech applications.
I have been using Django for 10 years and it still is my tool of choice when I need to build something quickly that needs a full HTML and form handling interface.
There is an excellent tool - https://djangobuilder.io/ that can also really speed up the boilerplate even more.
Django has been my go to framework for any new web project I start for more than a decade. Its batteries-included approach meant that one could go pretty far with just Django alone. Included admin interface and the views/templating setup was what first drew me to the project.
Django project itself has kept pace with recent developments in web development. I still remember migrations being an external project, getting merged in and the transition that followed. Ecosystem is pretty powerful too with projects like drf, channels, social-auth etc., covering most things we need to run in production.
https://github.com/trypromptly/LLMStack is a recent project I built entirely with Django. It uses django channels for websockets, drf for API and reactjs for the frontend.
IMHO Django is what really catapults Python as one of the leading contender of interpreted programming languages for web development in the presence of the other popular ones namely Perl, Ruby, TCL and PHP. After many people started using Python for web development made popular by web framework like Zope and Django, then they stay and keep using it because it's relatively easy to program. Above all it's easier to grok and maintain due to its ancestor being ABC language. It also adopted identation and made it mandatory mainly for readability reason since most of the popular programs has more than one programmer or maintainer.
Initially though Python got a lot of flak for this mandatory identation feature but later it's really its main advantage against other interpreted programming language of its time and programmers consider it a language with pseudo-like codes, but with functionality. Then come the era of data science and analytics popularity where Fortran and Matlab were kings, but the former is too primitive and the latter is a proprietary language. Interestingly, Guido himself was involved with new Python matrix operation syntax in order to make it more intuitive. Due to the rise of AI and machine learning where matrix operations are pervasive, Python becoming the best open source alternative and the rest is history. This is a very interesting read on HN for the reasons why Python win over its competitor and now the most popular language on the planet:
I write and maintain content for a living. Switching to a static site generator is the best thing I have done for my productivity since I started that website.
Powerful text editing tools I'm familiar with, source control, fully offline work, and very lightweight tooling that starts quickly (just a python script).
god i love django. it could use a little bit of modernization and modularization to ease the json api and deploy pain points, but it's still the best python web framework by a long shot and it would be deserving of way more manpower than it has.
but emoji laden docs and 500/month patreon pay better than contributing to established things i guess
This. I found DRF gets very confusing with all the abstraction for complicated stuff. For simple APIs, it's very nice (I used it on govscent.org). SidewaysData uses Ninja and I love it so far.
Yes, absolutely know DRF. The only problem is that DRF adds another very heavy pile of documentation to read to start working with it, with some footguns (e.g. ModelSerializers being very very slow, at least some years ago).
I'd rather have DRF (a subset maybe) inside django. No external dependencies and integrated auth could enable interesting patterns like complete modularization of the admin panel, making it json api driven and making deploys very easy such as `python manage.py generateadmin` and you can load that on S3 or whatever.
I also know the existence of whitenoise + many workarounds, but python is already a quirky language, django has its own and its starting to have a huge chunk of incidental complexity (my last django project, very mature codebase, had like 3 libs to work with JWTs...) to work proficiently with. Not to mention the footguns of it!
People like options, but with opinionated frameworks I'd rather have lack of them.
This is how simple Django is for CRUD apps. The author could go even sparser. Love them or hate them, the views could have been replaced with class based model views for even less lines of code.
Fewer lines of code, perhaps, but in terms of explicitness, clarity, and ease of maintainability I find myself strongly favoring the functional approach for this case.
I've been using Django for a number of years now and it's my go-to for any web app that requires any kind of dynamic content (especially user generated). DRF similarly for any REST related work fits in perfectly, but aside from that it's really refreshing to have a framework which doesn't require a tonne of other dependencies to get something decent off the ground.
If you want a more "out of the box" solution, you can run Wagtail and Puput on top of Django. The Puput default template is a bit dated, but it's pretty easy to update and tweak to your preferences.
Ask HN: I plan on developing and deploying a bunch of Django apps in the coming months as I’m doing a 3 month stint at https://recurse.com
GitHub Pages is great for purely static content - but what is the preferred/""best""/cheapest option for django/postgres hosting?
I know there’s tons of options - I used to be a Heroku fan until recently. Now am on Render (where things get expensive)
Is Pulumi/Terraform/IaC on AWS the way? I want git-deploys, not have to write .sh scripts to restart nginx and pip dependencies that auto un/install if possible.
I also thought of deploying one mega django project and having everything be a django app under that - it doesn’t feel sustainable/clean but maybe it’s ok for a bunch of small projects?
I use Dokku for side projects, where I don't expect high traffic, I'm the sole developer and I don't want any unexpected invoices I might get from a cloud provider.
You can run it on top of a single cheap VM, for example Digital Ocean or Hetzner, for a few dollars/euros a month. It is compatible with a lot of Heroku buildpacks e.g. PostgreSQL and Redis, has a similar CLI, and includes plugins for things like LetsEncrypt that can be installed with a couple commands. As with Heroku and other PAAS you can deploy with a simple git push.
It's absolutely fine for the MVP stage of a more serious project, but it's not really meant for scaling out beyond a single server. I mean sure, it's possible, but there are better tools for the job, and at that point you should have a bigger budget/team.
If you're not deploying at large scale, I'd go with something elastic in the same vein as Render (I haven't used that one though). Heroku used to be my go-to recommendation here of course. Fly.io gets a lot of love as a Heroku replacement and they have a generous free tier (though they have had some uptime troubles recently).
Alternatively GCP and AWS both have elastic compute options that should work as well. (App Engine and Beanstalk? respectively.)
Running a VM is going to be annoying (way more ops toil) and cost you more than you need, if you're making on the order of requests-per-hour instead of requests-per-minute. But if a VM is cheaper than your best elastic option you can make it work. I would not recommend sharing apps within a project as migrations can be annoying and you'll get downtime on every app whenever you deploy or break any of them. But you could have one VM serving up lots of projects, and give one port per project, then wire up a load balancer & DNS name for each project/port.
It's possible to do git-deploys with a VM but it's a little work to wire up. You'd set it up with GitLab, and you can wire up a simple deploy script that effectively does a `docker stop && docker run` to launch your new app container.
I use GitHub actions to automate test / build / deploy of django / Postgres / nginx docker orchestrations.
I prefer digital ocean for VPS and have found you can get pretty far on the smaller droplets.
I’ll typically have two environments, one getting auto deploys from anything on a feature branch, and production which gets deployed when there are changes to main.
For my setup, I initially learned using blog entries from the folks who blog at:
I really like Django and rails but here is how you make a blog: you choose a hosting package and pick your domain name for about 48 dollars per year. Then you create an index.html file and upload it. This file is your blog, you add <sections> that start with the date and below that you write your stuff for that date and each time you reupload the index.html. When around 365 days have passed you rename index.html to lastyear.html and start a new index.html that has a link to lastyear.html and that’s basically it. Have fun and don’t put too many images on the page.
This might be a dumb question, but would you use the deployed version of the admin interface for writing your blog? And what if you weren't online but wanted to work on a new essay or make edits to an existing post?
Just a question, is it possible to have a website built with Django and still work like the speed of a static site.
I've seen all these JAMStack websites marketed as 'fast' when the only reason they are fast is that these web frameworks (11ty, Astro, Hugo, Gatsby, etc) are essentially static generators to HTML which is pretty much the same as creating a plain html file if you want to.
I'm mainly interested in the SEO and speed side of things but does using a web framework like Django or an SSG make a difference?
Computers are fast these days. If you write efficient code I don't see any reason the difference between a Django site and static files couldn't be imperceptible.
Or... run a Django app behind a caching proxy like Varnish or Fastly or Cloudflare. I do that for my https://simonwillison.net/ site (Cloudflare) and helped implement Varnish at Eventbrite - it's a really solid pattern.
Nice and simple. I feel the only lacking feature for a basic blog is having unlisted blog posts, which is very handy when you want to share it to proof-readers. This can be done on google doc/hedgedoc [0] for sure, but then when porting there are very often typos creeping in.
The functionality exists in the author's implementation. If you search for 'is_draft' you'll come across the places in the code where this is implemented.
This is great and I love the simplicity and speed (of page load and development). Curious, I ran it through Lighthouse and received a performance score of 100. By way of comparison, some of the more notable blogs on cloud edge were consistently between 60-80. Just checking my perceptions.
How do people feel about Django vs flask in 2023? Just trying to farm for other's experiences because I find flask easier to start off with but I suspect I am biased.
Every sufficiently large Flask app reimplements half of Django, badly.
I’m the sole maintainer of a Flask app that uses SqlAlchemy, and the experience is similar except that I really miss the admin and auth. However every single flask app ends up using slightly different libraries and architecture, which means that onboarding always takes longer than an equivalent Django app.
Also, I have over a decade of Python experience; I wouldn’t count on people with little Python experience to produce well architected apps in Flask, whereas Django does a lot of guiding the user towards established patterns.
Some parts of Django are antiquated and I do not recommend them (specifically the Forms API really has been superseded by pretty much any newer forms library), but that’s still way less baggage than having to pick up a new stack for every new Flask app.
When I started using Rest Framework as I had more need for API endpoints than HTML pages I realized the Serializer API was way easier and more intuitive and pulled more weight. Then I began using Pydantic and its API design does pretty much the same except for the rendering part.
I think the rendering aspect in the Forms API has always been a PITA and the validation aspects always left something to be desired. Rendering and validation/serialization should be decoupled IMO, and in that sense the Forms API fails.
Sometimes I wish for the Django admin to be reimplemented in FastAPI/SqlAlchemy as a more modern approach to the same problems.
Due to $WORK factors, I have to write Flask, and I hate every second of it. So many things which come for free from Django require a partially supported plugin with so-so documentation.
Could Django do some things better? Sure, but it gets so much right, and has so much community support, it should be the default answer. If you ever get stuck with a problem, thousands of others have faced the same thing. With Flask, owing to your special snowflake configuration of extensions and wiring, you may not find any guidance anywhere.
Flask works for simple projects but as your needs grow, the built-in and extensive Django ecosystem will have you covered. And as seen above, Django in its simplest form is no more complex.
Some people really don't like the Django ORM, so in this case you might avoid Django altogether. It's possible to use Django without its data layer but it's a big part of its value.
Also if you are building a pure API project, FastAPI is worth checking out for a streamlined process. Django Rest Framework works too, but is an extension.
I do think leaning on the Django ORM for so many years has hurt my ability to write SQL on its own, but it's just about the only ORM thats ever clicked for me in that way.
That's a cute trick with the ATOM feed content-type. Simple idea, that probably(?) will not trip up any dedicated readers, but makes a nice usability win.
In order for that to work, the browser would have to actually implement an XSLT engine. I thought they all stopped shipping such engines about 10 years ago.
If you mean postprocessing the feed server-side with an XSLT sheet, to then serve the resulting page: sure, that would work, and a lot of people used to do things like that around 2003. It fell out of fashion because XSLT is just hard to safely combine with advanced JS-based features.
Strange, Chrome and Safari on OSX still render xml with referenced xsl stylesheets just fine (pointing to 192.168.x address). Browsers still have XSLTProcessor accessible in javascript too so I'm guessing they still have XSLT engines.
Yes, it does. Each Datasette Cloud user gets their own dedicated container, run using Fly Machines.
The core Django app manages SSO and team creation, then calls Fly APIs to create volumes and machines for each team. I'll be writing this up in a lot more detail soon.
I'm finding stability on Fly is excellent for my deployed containers.
The problems I've seen are more around deployment - occasionally there will be incidents where fresh deploys can't go out for a few hours, all of which are reflected on https://status.flyio.net/
For building CRUD web apps Django and Rails are truly in a league of their own[^1].
Many frameworks try to be good at this but finish development at a level of abstraction below these frameworks, leaving the last level to a plugin ecosystem that requires so much more work to wrangle into a fully working web app (see: Flask and its modern successors in Python).
Other systems come at this from the opposite end, trying to be low-code or less-code, like headless CMSs or static site generators. The problem at that end always seems to be a lack of flexibility and over-reliance on proprietary systems or SaaS products.
Django is just Python. Rails is just Ruby. There's nothing special to them and extending when necessary is often trivial, particularly because they have such mature extension points.
There's a lot of criticism that can be levelled at these ecosystems for not keeping up with whatever the hype of the year is, or failing to "scale" in various ways, but damn do they get you a very long way with very little work.
[^1]: Phoenix may be just about in this category, I don't have personal experience with it though, just going on the fact it seems to be very Rails inspired.
> Django is just Python. Rails is just Ruby. There's nothing special to them and extending when necessary is often trivial, particularly because they have such mature extension points.
Eh, I wouldn't agree with that. Both Django and Rails extend the languages quite a bit with deep class overloading, reflection and fluidic approaches.
Especially Rails, which pushes Ruby's DSL-like abilities to an extreme. If you go from learning RoR to then having to make a standard Ruby script, you quickly realize how much of what you built relied on Rails-specific functionality. Django, more or less, is just Python with a bunch of logic built for you, relative to that.
As someone who's been using Django for the past 12 years in apps big and small, it blows my mind the trends towards microframeworks and minimalist frameworks that are objectively less productive in pretty much every metric.
Sometimes it feel like a minor superpower in just how much more productive it is over pretty much everything, especially in the early stages of development.
Even later on things like working auth and permission systems and API frameworks are huge timesavers.
I've not seen another ORM with tools as powerful as Django's select_related() and prefetch_related() when it comes to addressing the N+1 query problem, but maybe I haven't been looking hard enough.
I believe these complaints may be caused by lack of experience with Django:
- There is nothing wrong with the ORM, you may be resorting to using deferred attributes too much. There are ways to eliminate them (select_related, prefetch_related) if you are having performance issues.
- Jinja2 has been a supported templating engine for years.
- I don't understand the question about static type checking. Can you elaborate?
I think of the all the ORM's, I've ever used. Django was the greatest.
However django is living in the age of past glories.
The admin is extremely unacceptable for anything beyond trivial borderline trivial use cases, and the modifications you'd have to make are just awful especially the more interactive something needs to be. The extremely tight integration between models and the modeladmin is a blessing and curse.
The people who like Django,also tend to overload it to do everything. This makes sense at small companies. The only place I really see Django at large companies is as an api using DRF or something.
For internal admins, I've been lobbying to use https://directus.io/ at my company.
> The only place I really see Django at large companies is as an api using DRF or something.
This is not a bad thing. Using Django as an API backend is amazingly fast in terms of development time, especially with modern frameworks such as django-ninja [1].
Just use the built-in ORM to create models, write your endpoints, and use the built-in admin interface to play with the database if you don't have endpoints for everything.
There is also a less known feature of Django called admindocs [2], which automatically generates a human readable, hyperlinked documentation for your models and relations between them.
And with Django you often don't need to write anything.
You're right to some extent with all of your points (jinja2 is available, not default, ORM is equivalent to SQLA most but not all of the time), but they're one side of the trade-off. The other is that you're writing admin views that you likely wouldn't need to with Django.
It's not perfect for everything, but it is much faster to write with than anything else for reasons like this.
- Seamlessly integrates with any django website, or hold your hand to create one from scratch.
- Play nice with the whole django ecosystem.
- Is easy to pick up because under the hood "it's just django". It uses django models, routing, auth, etc. It's uses standards, best practices, and is a good citizen.
- The blog admin and the provided block editor are good out of the box.
- It still gives you all the flexibility you want: it doesn't force any template on you, any page structure, workflow, nothing. You get to decide how simple or complex you blog is.
We moved away from wagtail and it was a bit of a mess to maintain after using it for a couple of years for our marketing website. I think I'd have stayed with native Django if I had gone back in time. In the meantime the team that manages this switched to next.js instead and it's been the most stable / productive setup so far for our marketing website. This being the 4th tool in 8 years (marketing people change their minds a lot).
Thanks for the comments. Did not know much about wagtail until now. Looks worthy of consideration for a side project I am considering.
If you don't mind answering a couple of questions:
- I have a requirement for basically a CMS with the capability of serious extensibility, built in either python or javascript (I considered ghost but it does meet my requirments). Main job is for a membership based cms but to potentially add functionality outside of standard cms stuff. Would you say wagtail / django combo would meet that requirement? (Sounds like "yes")
- How does wagtail compare to django cms? (Less interested in feature comparisons, more interested in your developer experience with both)
Static sites are a PITA when you need to add certain functionality. It's an optimization. Why start with such a crazy optimization when you can just put cloudflare etc in front of it?
Source: the fastcomments docs, blog, and several of my sites are SSG. I don't like it anymore.
Weird to see the notion of taking the documents you want to publish and saving them as documents be called "crazy". Publishing a blog post is just document preparation—you know, desktop publishing.
I'd call the let's-insert-an-unnecessary-database-here outlook the crazy thing. Not to mention, basically a violation of the Principle of Least Power <https://www.w3.org/DesignIssues/Principles.html#PLP>.
Because that's not what a blog or documentation site is. They usually have a ton of other features. sorting, searching, embedded dynamic widgets, code snippets, maybe code snippets pulls users account id and prefills it, and so on...
> Because that's not what a blog or documentation site is.
K. Ignoring that...
None of those are prerequisites. They're not listed by the author of the post linked here as among the features that he considers "essential for a blog in 2023" (nor are they even present on the Datasette Cloud blog that is the subject of the post), and it's not a "crazy optimization" to not go out of your way to introduce them.
(Is he, in your view, not actually running a blog?)
It is a crazy optimization. I cannot be convinced otherwise at this point.
Static sites sound nice and clean to a junior dev, I get it. But after using that approach for years I'll never do it again. Too much of a pain as things grow. Build step can also get slow. Django is so easy to use and extend. You can use it with sqlite, no DB to run.
Wikipedia is a nice example. Could that be SSG. Yes. Is it, and should it be? No. If your site has more traffic than Wikipedia let me know.
Do you know how much support calls I have to field for fastcomments with people trying to integrate into SSG systems with SSO or whatever that would be simple with SSR etc? A lot.
Wikipedia is a wiki. Blogs are not wikis. Blogs do not require a wiki engine. Wikis do. The statement "Wikipedia is a nice example" remains an abomination.
I am thinking of documentation sites and blogs in the same categories, because I use them similarly. I create blog posts (documents), they have titles, categories, and they link to each other.
I'm being a bit dramatic, but it's to stop people from using SSG. I don't like working on said applications because adding every little feature is a pain and adds to the build time. Running a simple service and DB is easy - I've been doing it for a decade. I ran blogs and sites with databases when I was in HS - surely big companies can do it and put cloudflare in front of it.
I switched from a dynamic to a static site even with Cloudflare in front because I didn’t want to have any active endpoints, period. Much less hassle and worry, plus the hosting costs decrease by an order of magnitude (just dump HTML into a storage bucket, zero VMs).
Well, taoofmac.com has 20+ years, 9000-odd pieces of content (that translate into 47.000 blob storage items), multiple navigation constructs (archives, backlinks - it’s a wiki - and even a 3D sitemap), and an incremental build for a post that links to 5-6 others (and resizes images, updates the home page, archives, linked page footers and backlinks) takes ~10s, including uploading the results (and an updated SQLite database) to Azure.
I use SQLite FTS for full-text search (it’s the only non-static endpoint).
A full site re-render on a Raspberry Pi takes 5 minutes, and a full reindexing - FTS plus linkmap - plus publishing around 10, but I only do that yearly or when I update things like CSS, layout, etc.
It all runs off a Git hook, uses SQLite to hold all the FTS, base HTML and metadata, and is as asynchronous as can be (including my own asyncio blob upload library). Costs me effectively zero.
I want to be able to hit edit on the post, do it right there, save and see my change immediately. I could set that up with a static site system but.... the admin I made for editing the post would remain the same. Furthermore the editor I have has a bind for CTRL+V that checks for images and automatically uploads them but also inserts an html tag for the media I just uploaded. This is something that is a terrible experience when editing a git repo having to manually link images and other media.
This doesn't provide a counterpoint to the original comment's point.
IMHO, it's true that a static site generator should be the way to go in 2023, instead of using a web framework with a db.
I am personally running a hugo blog, on netlify, with netlify CMS. I have 0 costs, great performances, everything needed out of the box. What else to ask for ?
In my blog, comments are not supported, and it would be easy to add if I developed my own blog with Django. But I feel that this single feature does not overweight the simplicity and velocity I have with such setup.
In regards to the requirement to know Git: It is just necessary in the setup phase, the blog posts creation and edition are controlled through Netlify CMS for me.
It's really not a good idea to use dynamically generated pages to run a blog.
There's a reason static site generators exist. This should be made clear that this is just a toy/example app to demonstrate Django, not something someone should actually use.
Generating the pages on each request is madness, and is why Wordpress in the default configuration (without WP Total Cache, which allows the httpd to bypass Wordpress entirely for most requests) falls over as soon as it's linked from any media site. Let's stop repeating these engineering mistakes in language after language.
Compile your blog to static pages and deploy those. Hugo, Jekyll, and a million others await you, as well as CF Pages, S3, GitHub Pages, Netlify, and others.
What a strange comment. Yes, caching is intelligent and will help you scale, but there's nothing inherently wrong with dynamically generated pages.
> Generating the pages on each request is madness, and is why Wordpress in the default configuration (without WP Total Cache, which allows the httpd to bypass Wordpress entirely for most requests) falls over as soon as it's linked from any media site.
No, it is not. WordPress is slow because it has an exceptionally poorly designed database schema, which requires SELECT DISTINCT and joining on the same table multiple times per query in order to do anything meaningful.
> Compile your blog to static pages and deploy those. Hugo, Jekyll, and a million others await you, as well as CF Pages, S3, GitHub Pages, Netlify, and others.
One downside of this is that you have wait for a compilation process every time you make content changes. Another is that any forms you might have still need a backend of some kind. Static sites are really only appropriate for sites that rarely ever change. A blog may or may not change frequently enough to warrant a backend.
You're conflating build times and deploy times. A low friction deployment might take a couple minutes end-to-end for something that "builds" in a few seconds once the CI is booted up. Sure, that's fine for hobbyist stuff that is always being edited by the web developer and nobody else. The point is a proper backend editing experience brings so much to the table. Once upon a time, my promotion was delayed because the team lead I answered to decided to use a SSG instead of a proper CMS, and non-technical stakeholders were not happy about the limitations.
Here's a post I put up just a few weeks ago showing how a completely dynamically generated blog with zero caching or performance tuning handles the traffic from ending up on the front page of HN, being served off the free tier of Fly.io: https://thraxil.org/users/anders/posts/2023/08/19/hn-traffic
It's Phoenix in my case, but I've had a dynamic blog with Django for a long time and it's not massively different in terms of performance. I also do like static site generators, but more for being able to dump stuff into S3 and avoid some deployment complexity (but they introduce other complexity).
The main point is really that Wordpress, with the default configuration is just off the charts terrible. Like, it had to have taken massive amounts of engineering to make something that performs so poorly. If you don't pile a million features into a product and overengineer the living daylights out of it, it's really not very hard to handle quite a bit of web traffic.
If you're worried about traffic spikes, stick your site behind a caching proxy like Varnish or Cloudflare.
My main blog https://simonwillison.net/ runs as a Django+PostgreSQL app on Heroku behind Cloudflare, with a 15m cache TTL for every page.
This works perfectly. I survived a surprise Elon Musk tweet a few months ago which the server didn't even notice, because Cloudflare absorbed all the traffic: https://simonwillison.net/2023/Feb/17/analytics/
Same, a bit of caching and the REVSYS blog survived being on the front page of Slashdot (back when that was a thing), Reddit and HN all at the same time. No Elon tweet for sure, but caching like Varnish, Cloudflare, Fastly etc go a LONG way.
There are other ways one can cache dynamic blog pages, like with CLoudflare. Some frameworks will automatically cache database calls as well, like with Rails.
One catch: I like to deploy static sites to GitHub Pages. It turns out the Django ecosystem has an answer for that in the form of Django Distill [1]. Distill adds a new management command that generates static content by repeatedly invoking your views.
I've used Distill to build quite a few static sites. It's great to be able to deploy to Pages but use Django's admin UI locally. Typically, for these sites, I check in my 'production' SQLite database directly to my git repo.
(Combine this pattern with GitHub actions and you can do a lot with a little. For instance, here's a toy I built to summarize upcoming Seattle city council meetings [2].)
[1] https://github.com/meeb/django-distill
[2] https://scc.frontseat.org/ -- source at https://github.com/front-seat/engage