I like the idea Russ - from a brief peruse of the code base it's apparently
to me how disparate the handling of various "setup" settings is throughout
the codebase. For example:

INSTALLED_APPS is handled by django.setup() and Apps.populate() (cached
attribute)
MIDDLEWARE_CLASSES is handled by BaseHandler.setup_middleware() (done once
and cached)
ROOT_URLCONF is handled by BaseHandler.get_response() (done every request)
DATABASES is handled by ConnectionHandler (cached property)
DATABASE_ROUTERS is handled by ConnectionRouter (cached attribute)
TEMPLATE_LOADERS is handled by find_template() (saved in a global)
CACHES is handled by CacheHandler (saved in a threading.local())

etc.

Perhaps there is an interesting possibility here to move some of these
disparate "inspect settings, import or configure some stuff and store it
for the duration of the process" onto a "global" object - something like
ProjectConfig. It could have methods (cached properties?) like
.get_middleware_classes() which would return the imported, configured
middleware classes. We then (dun dun duuuun) introduce a setting
PROJECT_CONFIG = 'django.project.ProjectConfig' which you can then set
yourself if you want to do a more procedural approach.

In a sense, this does nothing. It doesn't remove global state (still lives
in settings/project config), and it doesn't really change anything for most
users. What it does do is start the "centralize" the configuration and use
of settings, giving us 1) a way of changing how a setting is used, not just
defined and 2) the option of not setting that setting at all and just doing
it directly. This may (or may not!) interact quite nicely with
override_settings() which simply does not work with some settings which are
cached forever.

What is also to me interesting about it is that we may be able to do quite
a lot of the work without breaking any APIs at all -
BaseHandler.setup_middleware() can stay, it just calls something else to do
the work.

</throwing ideas>


On 5 September 2014 21:21, Carl Meyer <c...@oddbird.net> wrote:

> Hi Russ,
>
> On 09/05/2014 10:38 AM, Russell Keith-Magee wrote:
> > The other way to resolve this would be to rethink the way Django starts
> up.
> >
> > Settings like MIDDLEWARE_CLASSES have always struck me as being a little
> > odd - they're not really settings, they're a way to configure the way
> > code is executed without actually writing and executing code. The same
> > is true of things like ROOT_URLCONF, a few of the template loaders and
> > path specifications, and so on.
> >
> > If we were starting green-fields, it seems to me that we wouldn't do it
> > this way; the Pyramid/Flask approach of doing this sort of thing by
> > actually defining code would make a lot more sense. Django currently has
> > a well defined, but opaque startup sequence where settings are loaded
> > and then the middlware, urlconfs etc are set up. The alternative would
> > be an explicit startup sequence that constructs the desired middlewares,
> > installs them into a root urlconf, configures loaders and so on, and
> > then sets the environment running.
> >
> > This should also avoids the circular dependency problem, because
> > anything that needs to do an import in the settings file would be part
> > of the configuration process.
> >
> > To be clear, I know this would be a huge change. If we went down this
> > path, we'd need to maintain the old/current way of deploying Django for
> > a long time. In the interests of getting started quickly, it might even
> > be desirable to maintain both approaches long term. But having an
> > explicit startup sequence would allow for complex middleware
> > configuration like this thread has proposed. I'm just throwing this idea
> > out on the porch to see if the cat licks it up.
>
> I think this is generally down a similar line as the proposals that have
> been floated in the past (e.g. in a talk that Alex Gaynor gave at
> DjangoCon(?) a few years ago) to move Django away from its reliance on
> process-global configuration.
>
> Currently in Django a "project" is (implicitly) just "a settings
> module". The way I could see your proposal happening would be to
> introduce a Project (or Config?) class (in any other framework it would
> be App, but in Django that name is taken) which exposes APIs for
> imperative configuration of things like URLconf, middleware, etc, and
> then is itself (or can provide) a WSGI application callable.
>
> Then any script which wants to "start" Django would have two options:
> call django.setup(), which implements the current "look for a settings
> module and configure an implicit Project based on those settings"
> startup, or instantiate their own Project instead.
>
> The knottiest problem with moving away from process-global config is
> that it allows for our current "simple" APIs (e.g. import a model class
> and query on it, implicitly relying on global DATABASES config; import
> "render_to_string" and render a template, implicitly relying on global
> TEMPLATE_* config; import "send_mail" and send an email, implicitly
> relying on global EMAIL_* config).
>
> It would be possible to bite off the "imperative configuration" piece
> without the "kill global config" piece, though - we'd just need to
> provide an API (an alternative to django.setup(), or perhaps just an
> optional argument to it) that lets you install your own Project/Config
> instance as "the implicit global Project/Config", and then go ahead and
> use all the relying-on-global-config APIs just as you do now.
>
> Interesting to think about, but also a big chunk of very hypothetical
> work :-)
>
> Carl
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/540A1B4B.8080009%40oddbird.net
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAMwjO1GMwXoyCL6-GRyFE_jcMDH%3D5zRot3vS5gXn7mN15DnCTQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to