-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Hi folks,

On Tue, May 07, 2019 at 10:53:37PM +0200, Aymeric Augustin wrote:
> If we're only talking about providing default values for settings, currently 
> there are two straightforward solutions:
> 
> 1. Like Adam suggested, access settings like this: getattr(settings, 
> 'MY_SETTING', 'my_default').
> 
> This works well when you access settings just once, probably at import time, 
> and cache their value.
> 
> Here's an example: 
> https://github.com/aaugustin/django-sesame/blob/070cdb3fcdfa6c7310d7461add328a8095148ff1/sesame/backends.py#L27-L34
>  
> <https://github.com/aaugustin/django-sesame/blob/070cdb3fcdfa6c7310d7461add328a8095148ff1/sesame/backends.py#L27-L34>

This approach, however, makes it impossible to use the decorators and
context managers from django.test that override settings. Of course,
there are other ways to tune those knobs in tests, but it takes away a
standard solution provided by the framework.

> 2. Set a default value at import time:
> 
> # apps.py
> 
> from django.apps import AppConfig
> from django.conf import settings
> 
> class MyAppConfig(AppConfig):
>     name = 'my_app'
>     verbose_name = "..."
> 
>     def ready(self):
>         if not hasattr(settings, 'MY_SETTING'):
>             settings.MY_SETTING = 'my_default'
> 
> If you have many settings, you can define defaults in a DEFAULT_SETTINGS dict 
> and do this:
> 
>     def ready(self):
>         for setting_name, default_value in DEFAULT_SETTINGS:
>             if not hasattr(settings, setting_name):
>                 setattr(settings, setting_name, default_value)

Nice, I guess it's been a while since I spent any brain cycles on this
topic, but this solution seems much less tedious than what I'd seen
back in the days of Django 1.4. Almost feels good enough, except for
the fact that it goes against what the docs say about modifying
settings.

> > On 7 May 2019, at 17:15, Christian González <[email protected]> 
> > wrote:
> > 
> > I myself am using an implementation like DRF does it:
> > 
> > https://github.com/encode/django-rest-framework/blob/e16273a6584f9657c1e5c388558e9c5c92e7ba38/rest_framework/settings.py
> >  
> > <https://github.com/encode/django-rest-framework/blob/e16273a6584f9657c1e5c388558e9c5c92e7ba38/rest_framework/settings.py>
> > They create a class "APISettings", and mimic the Django behaviour.
> > 
> 
> This is yet another approach. DRF relies on a single Django setting which is 
> a dict containing all individual DRF settings. Then it converts that Django 
> setting to an object and uses this abstraction to access individual settings 
> as properties.

This seems to have become one of the current best practices, but it
requires each reusable package that goes down this road to include a
bunch of boilerplate just to deal with default values for settings. I
suppose that boilerplate could be factored out into its own reusable
package, but my gut tells me that there must be a better way to handle
something as fundamental as providing defaults for settings.
Definitely a very subjective claim, but I just feel like this is
something that should be the responsibility of the framework itself.

> Here we're talking about something slightly different: formalizing how an 
> application can declare default values for its own settings — essentially a 
> per-app equivalent of Django's global_settings.py. To do this properly, we 
> need two things:
> 
> - a good convention for declaring these settings: I would find it elegant to 
> consider every uppercase class attribute of an AppConfig class as a setting, 
> but that might be too magic (and perhaps backwards-incompatible);

I definitely agree that this feels too magic-y. Maybe introducing a
class attribute such as “DEFAULT_SETTINGS” that would hold a
dictionary could work, though?

> - a way to insert them properly into the settings object: I tried to figure 
> out how LazySettings and friends handle global_settings, unfortunately there 
> are more use cases than I was willing to untangle tonight.

Another thing to possibly consider, what should happen if multiple
packages try to provide different defaults for the same setting? I
mean, of course, this has kind of been floated in this thread already,
but it would add one more item to the list of things affected by the
order of INSTALLED_APPS.

Cheers,

Michal
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEUX01Y24NsLRJUN8tcDtP8g8z+SUFAlzSo6gACgkQcDtP8g8z
+SX2iw//bKFrh4tfq2k1gefcSDzhOBclqK4e7er3hwq6bRhevLvIgqVo/i3pwxlj
qSVop7ZnbnNk60xsPXLzzlEokkj+QDwldAUsaswckHmdP7zs6UiYWXzvQYc7ufpA
/+lcF3LHrBdBBn77Ip0760KxRPX5kjC0gCPSLKPpiBKxwb+31jkjLHkgIzHiYmUL
VGzpxDxkL1qLNafefXgezL7+mcUb6Mgj+jnYe+zIWGjDN8HBSQfNcALiyHWY9p5q
SCMP2+dH4wL/CsTk8eUEZZwxjlk1X5t2WuoDUxZCqybf9hJG85SjqHGbwnFZI0ar
aE9BMEy+e7brZYO3sX3QFoMHM8I0PUBPIPLbQtuEDJdnp9r69TnyNDL4kA/b9T4P
MHlta99sOe0VGaXV9LoANypJVVAiIQGU3Wxz9EVdu7g+Fdd2Y3THwaWaKes6r6nC
295lnfJP0MEIO81VDTal571Zqkw+kpm0P4uJVPlI9xgnglHoYOU0Er85ajkopqSl
UzI1X7s1GXbfBvd0Ejc3NNyhZcaNOXx0LYkxXsGRd2F/WBluj9neJpZAhbrNBIdk
eeAeZa1akIs8mQgObFSLSIxTGK5L/M5R0/cLlSQStOtvFmD7mJSXLM08CbjNWVlk
plR85tQ+JNKyxjrAKj7xO7Ha0g7Oo/U9AnkIQwXTSrxncjTEKu0=
=2yXl
-----END PGP SIGNATURE-----

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/20190508093848.rvruv3qdw6vd22m3%40koniiiik.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to