As the lead developer on three Django based commercial saas products, there is a trade off. Spend your time reinventing the same basic things or spend your time building your product. Even the maintenance argument is really a trade off. When you are small, frameworks help by outsourcing a huge amount of labor. When you can afford more developers, you gain control and maintainability by ditching the framework.
Let’s take it for granted you’re using it with HTTP since it’s a web framework (this would all apply with WS).
You routes call your views. Your views load your models. These feed into your templates, which go into a response. You can tweak what’s going on at each step (DRF) but there’s definitely a way it’s all supposed to work together. It’s classic IOC.
All a Django View is is a function (or in the case of a class-based view, a method of the class) that takes a request object and returns a response object... this is pretty fundamental to HTTP, so any HTTP app will do this. Its not Django dictating it, its the nature of HTTP.
You don't have to use any of those parts of Django if you don't want to.
I often opt to use Jinja2 instead of the Django Template Engine. I happen to like the Django ORM, so I usually do use it, but you certainly don't have to, I have certainly used Django without models before. Your views don't do anything with models unless you tell them to.
Using Django for this is of course completely overkill, but using a known framework, especially considering that Django is what's used in other applications here, did have some benefits. All our devs having to fix something in this app, will immediately be familiar with it as it looks exactly like the other Django apps we have. No new way to do migrations, talk to the db, open a shell, log- and reliability setup is identical with other apps, etc. etc.
And just cuz it’s optional doesn’t mean it’s not frameworky. A solid platform just wouldn’t offer any frameworky elements.
If that is not dictating how you write your code, I don’t know what is.
Its not just Django that locks you in, it's all the third party apps people end up adding. All these integrate tightly with Django.
They often block upgrades as they have different python and Django version requirements.
I use Django and Rails as examples. Both are, indeed, "just a bunch of libraries". But many of those libraries, and especially their bundled collection, enforce certain behaviour, shape and architecture.
When you inherit from base-classes offered by a library, you are tightly coupling against that: i'd then stop calling it a library and call it a framework instead. The alternative would be a library that you inject, or compose.
There's a big difference between (Rails)
`class Project < ActiveRecord::Base; end`
and
class Project
def initialize(project_repo) # Ruby has no interfaces, but this would be something that has at least an `.add(project)`
@project_repo = project_repo
end
endThe first inherits, couples tightly to a bunch of libraries (ActiveRecord::Base really is just a bunch of modules that you could pick and choose) the former injects behaviour which might come from libraries, or might come from your own code.
(Genuinely curious as someone who's working on a similar idea in a different language)
On the opposite, I'm in love with pydantic. Like any other package, it has issues, but it tries to solve a single problem, it's concise, validators are explicit and readable.
Obviously I don't mean any disrespect towards DRF maintainers, they're doing an impressive job, a lot of people use and love their work (and I still use it everyday)
Django does not dictate the flow of your code. It provides some libraries and there are common patterns, but Django is more or less just a set of Python modules you can import and use as you want (A bit of configuration is done for you if you follow common layouts, but you don't have to and can manually do the configuration).
What dictates program flow is when you use HTTP with Django (What its primary use case is) but that is dictated by the request/response nature of HTTP not by Django.
You can use as little or as much of Django as you want. Naturally, the more of it you use, the more it does for you.