Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make magical importing optional #360

Open
spookylukey opened this issue May 3, 2023 · 0 comments
Open

Make magical importing optional #360

spookylukey opened this issue May 3, 2023 · 0 comments

Comments

@spookylukey
Copy link

spookylukey commented May 3, 2023

It seems that django-configurations provides a number of functionalities:

  1. A method for organising settings via inheritance hierarchies
  2. A bunch of utilities for defining settings based on environment variables, URLs etc.
  3. It's own way of defining and importing settings, via the DJANGO_CONFIGURATION variable, which involves a bit of "magic".

The first two are great, but it seems like this last part is really unrelated, and causes a lot of complexity and issues. The docs say:

Yes, it looks like magic, but it’s also maintainable and non-intrusive

I think this is a bit optimistic. It requires you to change your manage.py, or wsgi.py/asgi.py, so it is quite invasive, it monkey patches BaseCommand, it breaks any script that just uses django.setup(), and also creates a bunch of other bugs, such as:

Is all of this actually necessary, or actually worth it compared to other options?

My idea is that you would not have any import loader (or it would be optional). Instead, you'd have a normal settings.py file, which would contain something like:

from configurations import setup_settings

setup_settings(from_environment_variable='DJANGO_CONFIGURATION')

All of the magic needed would be in that function. It would ideally not do any monkey patching of Django, but it might well do some messing around with sys._getframe(1).f_globals etc. to populate the module.

In other words, you'd have a couple of lines of boilerplate in each project, but only in the settings.py file. The only magic would be that the settings.py module explicitly populates itself in an unusual way, and after that there would be zero consequences for everything else.

Proof of concept - settings.py:

from configurations import setup_settings

setup_settings()

print(A_MAGICALLY_CREATED_SETTING)

configurations/__init__.py:

def setup_settings():
    f = sys._getframe(1)
    f.f_globals["A_MAGICALLY_CREATED_SETTING"] = "MAGICALLY INJECTED!"

You could also pass in globals() like setup_settings(globals()) for even less magic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant