I think if Go shipped better support for auth/sessions in the standard library more people would use it. Having to write that code yourself (actually not very hard, but intimidating if you've never done it before) deters people and ironically the ease of creating Go packages makes it unclear which you should use if you're not going to implement it yourself.
I don't like flask because it seems just easy enough to be really productive in the beginning but you eventually need most of the things Django gives you. So I would rather pick up Django Rest Framework or Django Ninja than Flask or Fast API. In those cases I jump straight to Go and use it instead because the same library decisions on the Go side give me a lot more lift on the operations end (easy to deploy, predictable performance into thousands of requests per second if built correctly).
I agree with you that Django provides most things that an application will eventually need, and if I were managing a team that was starting a project from scratch I think Django would be a reasonable choice, but aesthetically something about it irritates me.
For one, I so migrations with raw SQL onto the server, I just don't trust it any other way and I dislike ORMs, I even dislike query builders.
But for a big framework like Django you can't remove those batteries easily and you have already strayed away from the narrow paved road.
If I'm spinning up an API endpoint for my existing stack, I'm picking flask ( well no I'm picking go because WSGI is a pain in the... to deploy ) purely because I don't need auth + rate limiting + an orm and all that. I need endpoints exposed to do what I need, literally the rest is already handled by my API gateway and it will be tied into our existing management dashboard.
Django may be great to spin up a quick project but I found I needed to stary for the paved road pretty quickly so I rather picked a different tool...
This doesn't apply to everybody either, for aome Django is the correct solution.
Having said that, I’d bet that the go community consensus is that you build one out yourself and reuse it. So most times I end up copy and pasting the same logic rather than recreating.
However, my personal projects have a different set of code I reuse (more CLI- and tool-heavy focus), and I'm sure other environments would have an entirely different set of reused code.
On the opinionated library side of things, I did follow LiveBud for a while, and Go-Micro but haven't really sat well with the experiences from those, given how they lock you in to different aspects of your stack.
These stuff are never really hard, but you will make countless vulnerabilities that way. The most important job of a good framework is cutting down significantly on the possible to get wrong use cases, exposing you to already safe APIs.
I'm currently moving 4 python microservices into a single go binary. The only reason they were ever microservices was because of WSGI and how that model works.
In any conventional language those are just different threads in the same monolith but I didn't have that choice. So instead of deploying a single binary I had to deploy microservices and a gateway and a reverse proxy and a redis instance, for an internal tool that sees maybe 5 users...
It was the wrong tool for the job.
Or kick of long running backend tasks in a other thread?
These are things that python forces you to do in a distributed manner. Partly because of the gil and partly because those pesky cloud native best practices don't apply outside of the cloud...
And well if I'm going to have to reimplment an http server not ontop of wsgi how about just using a different language that doesn't have those same fundamental problems for the use case...
There's things I would happily use python for. A webserver just isn't one of them.
I mean it takes 10 lines of code to have a webserver running in golang, the language is build for it.
Deploying a Python application: 1) Install python globally (oof) 2) figure out which venv system to use 3) copy project to server 4) install project to venv 5) figure out how to run it inside the venv so that it'll find the correct package versions from there instead of using the global ones.