Django aside, I think this is a really important point:
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.
This is the main reason I'm extremely disciplined about making sure all of my personal projects have automated tests (configure to run in CI) and decent documentation.
It makes it so much easier to pick them up again in the future when enough time has passed that I've forgotten almost everything about them.
I'm finding that in this build fast and break things culture, it is hard to revisit a project that is more than 3 years old.
I have a couple of android projects that are four years old. I have the architecture documented, my notes (to self) about some important details that I thought I was liable to forget, a raft of tests. Now I can't even get it to load inside the new version of Android Studio or to build it. There's a ton of indirection between different components spread over properties, xml, kotlin but what makes it worse is that any attempt to upgrade is a delicate dance between different versions and working one's ways around deprecated APIs. It isn't just the mobile ecosystem.
Django is objectively the most productive "boring technology" I've ever worked with for developing web applications. They don't regularly add too many bells and whistles on every release, but they keep it stable and reasonably backwards compatible.
Its crazy to me after all these years that django-like migrations aren't in every language. On the one hand they seem so straightforward and powerful, but there must be some underlying complexities of having it autogenerate migrations.
Its always a surprise when i went to Elixir or Rust and the migration story was more complicated and manual compared to just changing a model, generating a migration and committing.
In the pre-LLM world, I was writing ecto files, and it was super repetitive to define make large database strucutres compared to Django.
Going from Django to Phoenix I prefer manual migrations. Despite being a bit tedious and repetitive, by doing a "double pass" on the schema I often catch bugs, typos, missing indexes, etc. that I would have missed with Django. You waste a bit of time on the simple schemas, but you save a ton of time when you are defining more complex ones. I lost count on how many bugs were introduced because someone was careless with Django migrations, and it is also surprising that some Django devs don't know how to translate the migrations to the SQL equivalent.
At least you can opt-in to automated migrations in Elixir if you use Ash.
well in elixir you can have two schemas for the same table, which could represent different views, for example, an admin view and a user view. this is not (necessarily) for security but it reduces the number of columns fetched in the query to only what you need for the purpose.
There is no way to autogenerate migrations that work in all cases. There are lots of things out there that can generate migrations that work for most simple cases.
oh the automatic migrations scare the bejesus out of me. i really prefer writing out schemas and migrations like in elixir/ecto. plus i like the option of having two different schemas for the same table (even if i never use it)
The nice thing in this case is that Django will meet you where you are with your preferences. Want to go the manual route? Sure. Want it to take a shot at auto-generation and then you customize? Very doable and. Want to let Django take the wheel fully the majority of the time? Sure.
I have never done it, but I believe you could setup multiple schemas under the same database -by faking it as different databases and then use a custom router to flip between them as you like.
That sounds like the path to madness, but I do believe it would work out of the box.
It is not much code to setup the router. Now, why you would want to bounce between schemas, I do not have a good rationale, but whatever floats your boat.
The author makes a great last point about Settings and it’s something I’ve not considered… ever! I wonder if there’s a feature request for this because having a pre-configured object would be nice for the ability to verify correctness on startup.
I use a project generator tool for a Django project. One of the things it does is generate setting file using string manipulation. I have been trying to think of a more sane way to do this. leverage something like dataclass or Pydantic models to have the typing information available and render a typed and validated Python object. If Django ever made that possible, it would be amazing for dev ex.
Thanks for this! I wish there were more cross-comparisons like this out there of what it is actually like to use some of these frameworks, the note on Django being a little less magic than Rails makes me genuinely interested in it.
No kidding, it is really good especially with htmx which helps you get some of the advantages of a full SPA without the complexity of a separate frontend.
Been building a project in the side to help my studies and it usually implement new complete apps from one prompt, working on the first try
After spending a lot of my time on Django, it's fine for simple to moderately complex things. The ORM mostly good. DRF is fine for APIs. And the admin is super nice as well.
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.
Alternatively look at https://sqlite.org/backup.html for backing up the sqlite db, instead of using VACUUM INTO
Django aside, I think this is a really important point:
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.
This is the main reason I'm extremely disciplined about making sure all of my personal projects have automated tests (configure to run in CI) and decent documentation.
It makes it so much easier to pick them up again in the future when enough time has passed that I've forgotten almost everything about them.
I'm finding that in this build fast and break things culture, it is hard to revisit a project that is more than 3 years old.
I have a couple of android projects that are four years old. I have the architecture documented, my notes (to self) about some important details that I thought I was liable to forget, a raft of tests. Now I can't even get it to load inside the new version of Android Studio or to build it. There's a ton of indirection between different components spread over properties, xml, kotlin but what makes it worse is that any attempt to upgrade is a delicate dance between different versions and working one's ways around deprecated APIs. It isn't just the mobile ecosystem.
Django is objectively the most productive "boring technology" I've ever worked with for developing web applications. They don't regularly add too many bells and whistles on every release, but they keep it stable and reasonably backwards compatible.
The Django ORM / migrations are still basically unmatched in happiness factor.
Its crazy to me after all these years that django-like migrations aren't in every language. On the one hand they seem so straightforward and powerful, but there must be some underlying complexities of having it autogenerate migrations.
Its always a surprise when i went to Elixir or Rust and the migration story was more complicated and manual compared to just changing a model, generating a migration and committing.
In the pre-LLM world, I was writing ecto files, and it was super repetitive to define make large database strucutres compared to Django.
Going from Django to Phoenix I prefer manual migrations. Despite being a bit tedious and repetitive, by doing a "double pass" on the schema I often catch bugs, typos, missing indexes, etc. that I would have missed with Django. You waste a bit of time on the simple schemas, but you save a ton of time when you are defining more complex ones. I lost count on how many bugs were introduced because someone was careless with Django migrations, and it is also surprising that some Django devs don't know how to translate the migrations to the SQL equivalent.
At least you can opt-in to automated migrations in Elixir if you use Ash.
well in elixir you can have two schemas for the same table, which could represent different views, for example, an admin view and a user view. this is not (necessarily) for security but it reduces the number of columns fetched in the query to only what you need for the purpose.
There is no way to autogenerate migrations that work in all cases. There are lots of things out there that can generate migrations that work for most simple cases.
Django manages to autogenerate migrations that work in the VAST majority of cases.
oh the automatic migrations scare the bejesus out of me. i really prefer writing out schemas and migrations like in elixir/ecto. plus i like the option of having two different schemas for the same table (even if i never use it)
The nice thing in this case is that Django will meet you where you are with your preferences. Want to go the manual route? Sure. Want it to take a shot at auto-generation and then you customize? Very doable and. Want to let Django take the wheel fully the majority of the time? Sure.
I have never done it, but I believe you could setup multiple schemas under the same database -by faking it as different databases and then use a custom router to flip between them as you like.
That sounds like the path to madness, but I do believe it would work out of the box.
sounds inconvenient and error-prone
It is not much code to setup the router. Now, why you would want to bounce between schemas, I do not have a good rationale, but whatever floats your boat.
The author makes a great last point about Settings and it’s something I’ve not considered… ever! I wonder if there’s a feature request for this because having a pre-configured object would be nice for the ability to verify correctness on startup.
I use a project generator tool for a Django project. One of the things it does is generate setting file using string manipulation. I have been trying to think of a more sane way to do this. leverage something like dataclass or Pydantic models to have the typing information available and render a typed and validated Python object. If Django ever made that possible, it would be amazing for dev ex.
Thanks for this! I wish there were more cross-comparisons like this out there of what it is actually like to use some of these frameworks, the note on Django being a little less magic than Rails makes me genuinely interested in it.
if you want "less magic than rails" check out ecto, i would say it has less magic than django
I always return to Django for any project. It's fantastic. Enough batteries are included with it that it is very powerful.
> I love being able to backup by just doing a VACUUM INTO and then copying the resulting single file.
Naively, I would probably just copy the sqlite file. Is that a bad idea?
That's fine if SQLite isn't running, but you risk corruption if you copy a file while it is being actively written to.
VACUUM INTO eliminates that risk.
I learned about the VACUUM INTO command through the following guide on how to backup your sqlite database: https://litestream.io/alternatives/cron/
I much prefer Python but am not really seeing any point to doing anything other than JavaScript for web projects at this point.
I also do not see much reason to do more than emit JSON on the server side.
Figuring out which "json" to "emit" is the hard part.
Claude Code is also very good at building basic CRUD apps with Django.
No kidding, it is really good especially with htmx which helps you get some of the advantages of a full SPA without the complexity of a separate frontend.
Been building a project in the side to help my studies and it usually implement new complete apps from one prompt, working on the first try
After spending a lot of my time on Django, it's fine for simple to moderately complex things. The ORM mostly good. DRF is fine for APIs. And the admin is super nice as well.
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.