Hacker News new | past | comments | ask | show | jobs | submit login
Notes from building a blog in Django (simonwillison.net)
214 points by theptip 8 months ago | hide | past | favorite | 136 comments



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].)

[1] https://github.com/meeb/django-distill

[2] https://scc.frontseat.org/ -- source at https://github.com/front-seat/engage


Your use case and workflow is exactly why I originally developed django-distill, glad to see it resonates with other developers. Thanks!


Thanks for Distill. The approach you took (specialized URL routes and custom management commands) is simple and elegant.


This sounds like an awesome pattern, and I had no idea it exists!


It’s a good one.

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!)

[1] https://simonwillison.net/2021/Jul/28/baked-data/


I say this as someone that does like Django.

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.


Your links may be broken

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.

https://instagram-engineering.com/types-for-python-http-apis...

https://engineering.fb.com/2023/09/07/culture/threads-inside...

https://engineering.fb.com/2022/05/02/open-source/cinder-jit...

https://engineering.fb.com/?s=django

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.

[0] https://you.23andme.com/ [1] https://api.23andme.com/


Was the blog post titled Django3andMe? :)


Lots of interesting links; thanks!

Here in Seattle, Rover (a $1B+ market cap company) also uses Django extensively. As do lots of interesting local startups.


That is sufficiently complicated. Thank you!


Whats your travelling startup?


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.


Thank you! I'll give that a gander.


You can also use wagtail with django-distill!



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:

[1] Ask HN: Why did Python win?

https://news.ycombinator.com/item?id=37308747


For a blog I prefer static site generators to be honest. Fast, cheap, secure and better for the environment.

Django and Wordpress are still valid use case for a blog.


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).

I wrote a bit about the experience here: https://nicolasbouliane.com/projects/ursus


I agree, I had my blog on Django, and the dynamic stuff was just minimal.

Then again, with Django-Distill (linked above), you can get the best of both worlds.


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


With regard to JSON API aspects of Django, have you used https://www.django-rest-framework.org/ on top of Django? I find it to be very satisfactory.


Django-Ninja is fantastic and based on pydantic.


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.


DRF becomes hard to understand when you use magical stuff like class based controllers and so on. stick to functions and it's actually very simple!


You're absolutely right - however I did not even know I could use functions. I didn't see that in the docs somehow.

Also I think I remember with DRF I had trouble generating a good openapi client. With ninja it works really well.


I much prefer Ninja as well. Is it active, these days? It feels like it's got much less of an ecosystem than FastAPI.


> Is it active, these days?

Yes. They are currently migrating to Pydantic 2 which Ninja 1.0 will be based on.


DRF has been fantastic in my experience, it fits in so well I often forget it's a plugin and not just a default part of Django


It's the only way I've used Django and I love it.


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.


Just for kicks I ran `git log | grep "Author: Simon" -C 20 | tail -n 50`

``` commit 53eddd4a0f8786e23f511a653d8d7ffa947ad8db Author: Simon Willison <simon@simonwillison.net> Date: Mon Apr 23 21:24:41 2007 +0000

    Added HTTP_HOST example header

    git-svn-id: http://code.djangoproject.com/svn/django/trunk@5063 bcc190cf-cafb-0310-a4f2-bffc1f526a37
```

There are earlier references as well, but I think the author was making pretty deliberate choices.


Yes, Simon Willison was part of the Django core development team very early on, when he was ungodly young. Absurdly talented guy.


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.


Big Django user and fan here!

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?

Thanks!


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:

https://testdriven.io/blog/

I blended multiple entries to achieve just the setup I wanted.

I haven’t gone up to terraform though, finding it sufficient to use a pre built image of ubuntu / docker at the initialization.

My oldest projects still use .sh to handle deploys but I’d never go back to that stuff.


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.


Bear Blog is a whole blogging platform running tens of thousands of blogs and is build in Django and running on pretty simple hardware.

Django really is beautiful.

https://bearblog.dev


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?


I usually write posts in Markdown these days, directly in VS Code with the preview pane open.

The blog described in this article renders Markdown directly. My https://simonwillison.net/ blog doesn't do that yet, instead I paste my Markdown into https://til.simonwillison.net/tools/render-markdown and then paste the HTML into the admin interface.


https://www.django-cms.org/en/ has blog with authentication etc, just a wordpress in python


Mojo?

Has anyone heard if Django (or FastAPI, etc) will be ported to Mojo programming language?

https://www.modular.com/mojo


According to the docs, Mojo is supposed to be a superset of Python, so technically nothing will need to be ported.


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.


The advantage of a static site is that your server is simple, fast and secure, and requires little to no maintenance.


Depends on how much work your Django app is doing. There's built-in caching support to make it faster.

https://docs.djangoproject.com/en/4.2/topics/cache/


Caching can make it really fast, and this is good if you expect your website to change often (e.g. due to comments).

Otherwise static is 100% the way to go, if only to reduce how much code to deploy.


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.

[0] https://hedgedoc.org/


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.


Nice, built bravoboard ideas blog with Django as well. Nothing too fancy. Django gets the job done!

https://www.bravoboard.xyz/ideas/


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.


Curious why you think Django Forms API has been superseded?

Are you recommending people use something like WTForms directly?


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.


This article is a few years old but it compares both really well:

https://adamj.eu/tech/2019/04/03/django-versus-flask-with-si...

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.


I wonder if it's possible or worth applying an xsl stylesheet or transform on this? Or would it create usability issues for dedicated readers?


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.

xsl-stylesheet with css works for me as well.


I remember seeing people try that fifteen years ago - it was a feature of FeedBurner, which ... apparently continued to work until 2021! https://www.ctrl.blog/entry/feedburner-2021.html


There was a discussion here about that in June:

https://news.ycombinator.com/item?id=36401854


Do your notes include how to recover from being hacked?


Do you know something I don't know?


No, just PTSD from my WordPress blog. I would use a static site generator if possible.


Hah, yeah securing something like WordPress can be a challenge, especially if you're running a bunch of plugins.

My blog is a pretty straight-forward Django setup without many other dependencies, so it's a lot less of an attack surface: https://github.com/simonw/simonwillisonblog


Be interested to know how/where it's deployed!


It's running here, hosted by https://fly.io - https://www.datasette.cloud/blog/


Does Datasette Cloud also run on Fly.io? How is Fly.io stability nowadays?


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.

Proof that we are a fad-driven industry.


And in exchange for a free auth system and a automatically generated basic admin interface you gain:

- inability to use static type checker without writing most of the annotations yourself

- half jinja2 functionality

- ORM that makes it impossible to get your query count down to a manageable level

- 3rd party modules that break the types even more

I am lobbying for moving to FastAPI with Jinja2 and SQLAlchemy. We write our admins in Vue anyway.


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.

Jinja2 is a supported template backend for Django these days: https://docs.djangoproject.com/en/4.2/topics/templates/#djan...


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 agree with these.

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.

[1] https://django-ninja.rest-framework.com/

[2] https://docs.djangoproject.com/en/4.2/ref/contrib/admin/admi...


> We write our admins in Vue anyway

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.


Django is Python, but very heavily leans on Python's metaprogramming, which can make things complicated to understand.


While this is a good example of all the good stuff raw django brings to the table, if you build a blog with django, you should go for wagtail in 2023:

https://wagtail.org

- It's incredibly more productive.

- 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.

- The team behind it is super nice.


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)

Thx in advanced!


Wagtail is not your usual CMS is that unlike the competition (such as django cms), it doesn't come with any kind of structure.

On one hand that means you have to do more work: define exactly what you want, then declare it in code, then build the templates.

On the other hand it means you can do exactly what you want, including the requirements you just mentioned.


Will wagtail work in 10 years from now? Being Python and Django, it just might. In the node ecosystem, things are broken after 10 weeks or 10 months.

The benefits of static site generations...


Wagtail first shipped 9 years ago in 2014. It's already old/boring, and great!


I wouldn't recommend people use anything that requires a database for a blog in 2023.

Edit: Since I got extremely downvoted for this comment. Here is why:

You should use static site generators for new blogs in 2023.

Performance: Static sites typically load faster than database-driven ones.

Security: Without a database, the risk of SQL injection attacks is eliminated.

Scalability: Static sites can handle high traffic without complex hosting solutions.

Maintenance: No database means fewer maintenance tasks and potential failures.

Hosting and Costs: Static sites often have cheaper and more flexible hosting options.

Decoupled Architecture: Modern trends prefer separating frontend and backend, reducing the need for databases.

Development Simplicity: Static site generators offer a straightforward content writing environment.

Backup and Portability: Static sites are easier to backup and migrate.

Edge Hosting: Static sites benefit from faster load times with distributed hosting solutions.


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 nice example. Could that be SSG. Yes. Is it, and should it be?

No, Wikipedia is a terrible example. Absurd, even. We're talking about blogs. We can stick to that example. We don't need to reach for bad ones.


Yeah? It's a bunch of documents that link to each other :) blogs do the same.


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).


Also Django and Rails are annoying as hell to deploy compared to just uploading a zip of your static site to a static site host.


With good caching and a CDN, you mitigate these issues. Database isn’t an issue.


for people disagreeing with this comment, mind elaborating?


My https://simonwillison.net/ blog has been running since 2002 and has 3015 long-form posts, 6718 bookmark posts and 770 quotations.

Plus tag pages, archive-by-date-pages, series pages and more.

I don't particularly want to have to wait for all of that to build!

It also offers faceted search against all of that, powered by PostgreSQL: https://simonwillison.net/search/?q=static%20site%20generato...


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.


That's awesome. Parts of that sound a little bit like how my https://til.simonwillison.net/ site works.


I need to update my write up, but this is generally it: https://taoofmac.com/space/blog/2021/06/19/2036


Incremental builds exist, so you'd really only have to build once: https://nextjs.org/docs/pages/building-your-application/data...

That said, personally, I love PG and enjoy using a DB. But I can see pro's to both sides.


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.

Code: https://github.com/hparadiz/technexus/blob/release/public/js... https://github.com/hparadiz/technexus/blob/release/public/js...


I think 800+ million Wordpress blogs are not planning to shut down in 2023 after reading GP's comment.


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 ?


Does your blog support comments?

Also, for a company blog, an SSG likely means a requirement to know Git, which could be inconvenient.


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.

If you really need comments in your blog when using Hugo, you can still integrate them with Disqus https://gohugo.io/content-management/comments/

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.


Interesting, thank you for introducing me to Netlify CMS, didn't know about it.


I don't think there are 800+ million WordPress blogs. WordPress is used for lots and lots of websites that are not blogs at all.


Thank you, I stand corrected, 800M+ WordPress installations.


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.


> 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.

Any modern SSG can build and deploy in under a minute, usually in single digit seconds. This isn't really an issue in practice at all.

Static sites work fine even if you are updating many times an hour. This is a far cry from "rarely ever change".


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.


As someone who uses a mixture (django, Hugo), I say it’s fine use dynamic sites to run a blog - there’s millions of them out there.

They are usually easier to administer for less professional users, as well as being able to quickly modify from standard web interfaces.

If it’s backed by a cache like redis it’ll easily handle Hackernews level traffic, even at very short cache times.


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: