> On 8 May 2019, at 11:38, Michal Petrucha <[email protected]> wrote:
> 
> 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.

I'm not sure I understand what you're referring to. The framework provides the 
setting_changed signal, which seems to work well here: 
https://github.com/aaugustin/django-sesame/blob/070cdb3fcdfa6c7310d7461add328a8095148ff1/sesame/test_signals.py#L8-L18

>> 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.

I'm ambivalent about this. I did it myself (TEMPLATES). I'm not sure that was 
worth doing.

Grouping a bunch of related settings in a dict looks satisfying. However, it's 
less practical than giving them a common prefix, notably to override them in 
tests.

I suppose I could support a well-written proposal, though :-)

>> 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?

Yes, it could work too. I considered it and didn't choose it because it 
increases the distance between what global_settings.py looks like and what app 
settings would look like. Not a very strong argument ;-)

Also there's already magic to include only uppercase variables currently: 
https://github.com/django/django/blob/ef9f2eb69c9396683cefa742bc7d0a0792090e8d/django/conf/__init__.py#L135-L137

>> - 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.

Yes. Since the semantic is "make this value the default if there isn't a value 
already" (i.e. setdefault), the most intuitive behavior should be "first app in 
INSTALLED_APPS wins".

Best regards,

-- 
Aymeric.

-- 
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/20D907CE-D92E-4EF5-8EF4-8AF87F646017%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to