Django
does have magic:
The key thing is Django's implicit behavior is directly proportional to the job it's trying to do [1]:
- Django's settings can be invoked at any time. So it's kept as a lazily-loaded singleton that isn't processed until an attribute is first accessed.
- Django needs to know which apps to load (a la INSTALLED_APPS). And to know the models, django needs to know the apps. These app models can contain relationship dependencies, so its necessarily from a invocation perspective to have a settings that declare them all.
- Using Django's initialization is a must. For the reasons above (settings), but there is work done behind the scenes to make sure everything lines up when Django starts.
- It's most likely project's using Django are going to be using it's ORM.
On the other hand:
- Django doesn't hold every project, or every request for that matter, to its batteries. Intricacies like middleware and context processors are opt-in. Things like template filters are also opt-in on a per-file basis via {% load %} tags.
- Whether or not to use Forms Framework / crispy-forms, for instance, is optional. But projects would miss out on nicely generated forms with validation.
- Projects can also switch out template engines for Jinja2 or something totally custom.
- While strictly speaking, projects can just keep models.py empty, QuerySet's are like the ultimate reusable interface in Django's Frameworks. QuerySet's can be used:
- by class-based views (CBV)
- ModelForms to provide database-backed form validation
- by third party extensions like Django REST Framework (DRF), django-filter, django-tables2, django-guardian, and so on
- in context processors (which can access URL regex group matches), that later are passed into in templates.
While that may feel like overkill, this is useful for things like database-backed menus that CMS like Drupal and WordPress would use by default.
> It's way harder to scale due to both its heavy reliance on hidden magic its tight integration with its data store.
I plan on making a future article diving into Django's ORM. Sure, ORM's hide a lot of machinery behind a facade of sugary objects. But on most web projects the database's aren't doing much more than simple joins.
Django's ORM can scale into medium-sized code bases. By the time it gets beyond the point the ORM can handle, heavier data tools (like ElasticSearch, Hadoop) would end up being brought in regardless of whether Django was picked. That doesn't mean earlier code or data schemas need to be thrown out.
Put it another way: When project's get to the point they need a datamart or other things, they're likely to create a separate service for that distinctive from the web front-end.
[1] https://www.git-pull.com/code_explorer/django-vs-flask.html#... / https://www.git-pull.com/code_explorer/django-vs-flask.html#...