jazzband / django-configurations

A helper for organizing Django project settings by relying on well established programming patterns.
https://django-configurations.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.09k stars 145 forks source link

values.SecretValue returning a SecretValue object #238

Open joshourisman opened 5 years ago

joshourisman commented 5 years ago

I have a Django 2.2 project that's using Django-configurations 2.1 and the Froala WYSIWYG editor with the django-froala-editor package (2.9.5). The django-froala-editor package expects a dictionary in settings called FROALA_EDITOR_OPTIONS that includes a key (named 'key') with your license activation key. Because this setting is only necessary in production, while the rest of the dictionary needs to be defined in development as well, I'm setting FROALA_EDITOR_OPTIONS in a BaseConfiguration which is inherited by my production configuration, which then includes the following.

    # Froala Settings
    FROALA_ACTIVATION_KEY = values.SecretValue(environ_prefix="")
    FROALA_EDITOR_OPTIONS = {
        **BaseConfiguration.FROALA_EDITOR_OPTIONS,
        "key": FROALA_ACTIVATION_KEY,
    }

I've used this pattern successfully in the past (and in this project, in other places, for that matter), but now when I load a page that contains the Froala editor I get an error, because it's attempting to JSON serialize the options dictionary, and Object of type SecretValue is not JSON serializable. It looks like settings.FROALA_ACTIVATION_KEY resolves to a string, as you'd expect, but settings.FROALA_EDITOR_SETTINGS['key'] is a SecretValue.

>>> type(settings.FROALA_ACTIVATION_KEY)
<class 'str'>
>>> type(settings.FROALA_EDITOR_OPTIONS['key'])
<class 'configurations.values.SecretValue'>

Is there a better pattern for doing this?

joshourisman commented 5 years ago

I was able to get it working by switching FROALA_EDITOR_OPTIONS in my production Configuration to a property, which makes sense when I think about it, but still not sure it's the best way to do it.

    # Froala Settings
    FROALA_ACTIVATION_KEY = values.SecretValue(environ_prefix="")

    @property
    def FROALA_EDITOR_OPTIONS(self):
        return {
            **BaseConfiguration.FROALA_EDITOR_OPTIONS,
            "key": self.FROALA_ACTIVATION_KEY,
        }