I'll add a few of my own:
* Set up the project using uv
* I name the django project "project"; so settings are project/settings.py, main urls are project/urls.py, etc
* I always define a custom Django user model even if I don't need anything extra yet; easier to expand later
* settings.py actually conflates project config (Django apps, middleware, etc) and instance/environment config (Database access, storages, email, auth...); I hardcode the project config (since that doesn't change between environemnts) and use python-dotenv to pull settings from environment / .env; I document all such configurable vars in .env.example, and the defaults are sane for local/dev setup (such as DEBUG=true, SQLIte database, ALLOWED_HOSTS=*, and a randomly-generated SECRET_KEY); oh and I use dj-database-url to use DATABASE_URL (defaults to sqlite:///sqlite.db)
* I immediately set up up ruff, ty, pytest, pre-commit hook and GH workflow to run ruff/ty/pytest
Previously I had elaborate scaffolding/skeleton templates, or nowadays a small shell script and I tell Claude to adapt settings.py as per above instructions :)
Being able to abandon a project for months or years and then come back
to it is really important to me (that’s how all my projects work!) ...
It's perhaps especially true for a hobbyist situation, but even in a bigger environment, there is a cost to keeping people on hand who understand how XYZ works, getting new people up to speed, etc.I, too, have found found that my interactions with past versions of myself across decades has been a nice way to learn good habits that also benefit me professionally.
As a mostly-django-dev for the last 15 years, who's been exposed to FastAPI and various ORMs again recently, I should get round to write a doc about some Django bits.
Django is pretty nice, the changes between versions are small and can be managed by a human.
Part of the reason that you can have the big ecosystem is that there is a central place to register settings and INSTALLED_APPS, middleware etc.
That enables addons to bring their own templates and migrations.
There is a central place a bit further up in manage.py and that enables you to bring commandline extras to Django (and many of the things you install will have them).
Coming to a FastAPI app with alembic and finding a lot of that is build-it-yourself (and easily break it) is a bit of a shock.
The Django ORM at first can seem a little alien "why isn't this sqlalchemy" was my reaction a long time ago, but the API is actually pretty pragmatic and allows easy extension.
You can build up some pretty complex queries, and keep them optimised using the Django-Debug-Toolbar and its query viewer.
The ORM, Templates and other parts of Django pre-date many newer standards which is why they have their own versions. As a Django dev I only just discovered the rest of the world has invented testcontainers, and databases as a solution for a problem Django solved years ago with it's test database support.
I quite like the traditional setup where you have settings/common.py and then settings that extend that - e.g local.puy production.py
If you ever need a CMS in your Django project I strongly recommend Wagtail, it came after the initially most popular django-cms and learned a lot of lessons - feeling much more like a part of Django.
It has the same feeling of being productive as Django does when you first use it.
Naively, I would probably just copy the sqlite file. Is that a bad idea?
But once something gets significantly complex, the ORM starts to fall down, and DRF becomes more of a hindrance.
But if you're just doing simple CRUD apps, Django is perfectly serviceable.
Re: Django is OK for simple CRUD, but falls apart on anything complex - this is just untrue. I have worked in a company with a $500M valuation that is backed by a Django monolith. Reporting, recommender systems, file ingestion pipelines, automatic file tagging with LLM agents -- everything lives inside Django apps and interconnects beautifully. Just because it's a Django app doesn't mean you cannot use other libraries and do other stuff besides basic HTTP request processing.
Recently I had the misfortune of doing a contract on a classic SPA project with Flask and sqlalchemy on the backend and React on the frontend, and the amount of code necessary to add a couple of fields to a form is boggling.
Django does not provide magic, but it's ORM is like pure sorcery compared to the garbage out there (SQLModel, etc.).
Django provides the necessary tools to build terrific software. However, it does not prescribe extra extraordinarily high-level architectural guidance, so it leaves that up to you. For example, if you are building an app that will have a main UI for users to login, a backend UI for managers to view reports, an API for consumption by outside developers, Django doesn't provide some kind of automatic recommended pattern for structuring your app to support all this. However, it provides the exact ingredients you need to do this on your own. In the example a gave, you would simply structure your directories to reflect the various UI / inputs modalities, and then point a path to each section (urls.py). If you want to host your API as a separate service, you just define a WSGI/ASGI app and pointed to a separate urls.py, then start that container using that WSGI/ASGI app, simple as that. Django does not have any kind of magical mono effect structure to it. It is just a collection of unbelievably useful and clean and simple API that you can use to compose software at least 5x more quickly then you can with e.g., FastAPI. I'm in the second team I've been in that is using FastAPI, and it is uncomfortably slow, you wouldn't even believe it. With FastAPI or other API/micro frameworks, I think the perception is that "it's just python" as if Django is something else, and so people start off app.py and they "see now I can start from this fresh canvas", and then they learn after spinning their wheels for two years that having a solid ORM is actually important, having migrations that are always correct and automatically generated is important, having an admin interface for viewing, creating, managing local/testing data while debugging things, etc. is important, having an ORM that lets you do aggregation and annotation so easily that you find yourself wanting to make reports just as an excuse to use these features, is important, having a template system that lets you generate dynamic pages without having to set up a full SPA for every little interface that you want to make allows you to make a quick prototype or even a permanent UI of some kind without having to involve a team of front end developers who will then begin to dictate your entire backend architecture through their litany of ever changing API endpoint requirements. Speaking of, the common pattern that I have noticed with SPA/API based develop is that the front end wants to be large and in charge, until it comes time to validate data inputs or have to do anything with data that requires looking at it holistically (for example, given a list of orders, if there are any orders that have items that are backordered, provide a warning at the top of the page… SPA developers completely crushed by this requirement, now the backend has to add additional information via the end point called "are there backorder items", etc.). So you end up with this hodgepodge of mess, instead of creating a prototype of your interface and then coming back and deciding which things need to be "reactive", and either shoehorning those things in or rewriting your UI because it's absolutely necessary.
This has become quite the rant, but as somebody who has worked on software for nearly 20 years and can hand write HTML, CSS, JavaScript, use Svelte / React, Python, Django, SQL, etc., I've learned a LOT and seen a lot and I can tell you absolute certainty that choosing Django for a new project is the absolute most effective choice you can make on your path to success.
IMO, type annotations should only be omitted in obvious cases or simple/MVP projects.
I also do not see much reason to do more than emit JSON on the server side.
It's a combination of things that all suck: the - ORM (sqlalchemy is better in every possible way. django's orm is very poor and can't express a lot of sql constructs at all) - templates (jinja2 is basically identical except performant and debuggable) - routing (lots of wsgi routers exist and are lightyears ahead of django)
Don't use Django.
Reference (me saying the same thing 16 years ago): https://news.ycombinator.com/item?id=1490415