bsd
bsd

Reputation: 1247

django config settings import issue

I have the following structure in a django project.

I have a providers.py file in which:

from django.conf import settings
from project.utils.firewalls import fw

In providers I need to get some vars defined in settings.

Then in firewalls.py, I have:

from django.conf import settings

Also in firewalls.py, I do have some code which needs to get a variable that is defined in settings.

When I try to do: python manage.py --settings=project.settings.local it will complain about not defining SECRET_KEY, although it is defined.

It has to do with the fact that I am importing django.conf.settings in both files.

How can I avoid that ?

For the moment I've hardcoded the value of the var in the firewalls.py, but I would like to avoid that.

Edit:

Add Stacktrack:

➤ python project/manage.py runserver --settings=project.settings.local               
Traceback (most recent call last):                                                   
  File "project/manage.py", line 15, in <module>                                     
    execute_from_command_line(sys.argv)                                              
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line    
    utility.execute()                                                                
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute    
    self.fetch_command(subcommand).run_from_argv(self.argv)                          
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv    
    self.execute(*args, **cmd_options)                                               
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 60, in execute    
    super().execute(*args, **options)                                                
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/core/management/base.py", line 353, in execute    
    output = self.handle(*args, **options)                                           
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 67, in handle    
    if not settings.DEBUG and not settings.ALLOWED_HOSTS:                            
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 57, in __getattr__    
    self._setup(name)                                                                
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 44, in _setup    
    self._wrapped = Settings(settings_module)                                        
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 107, in __init__    
    mod = importlib.import_module(self.SETTINGS_MODULE)                              
  File "/home/bsabin/Projects/repo/venv/lib64/python3.7/importlib/__init__.py", line 127, in import_module    
    return _bootstrap._gcd_import(name[level:], package, level)                      
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import                    
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load                  
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked         
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked                  
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module            
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed       
  File "/home/bsabin/Projects/repo/project/project/settings/local.py", line 1, in <module>    
    from .base import *                                                              
  File "/home/bsabin/Projects/repo/project/project/settings/base.py", line 21, in <module>    
    from project.utils.providers import AProvider, BProvider, CProvider              
  File "/home/bsabin/Projects/repo/project/project/utils/providers.py", line 6, in <module>    
    from project.utils.firewalls import fw                                           
  File "/home/bsabin/Projects/repo/project/project/utils/firewalls.py", line 29, in <module>    
    fw = get_firewall_instance()                                                     
  File "/home/bsabin/Projects/repo/project/project/utils/firewalls.py", line 11, in get_firewall_instance    
    token = settings.DO_TOKEN.get('token')                                           
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 57, in __getattr__    
    self._setup(name)                                                                
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 44, in _setup    
    self._wrapped = Settings(settings_module)                                        
  File "/home/bsabin/Projects/repo/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 126, in __init__    
    raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")                                                                                                                                                                                                                                                  
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty. 

Upvotes: 0

Views: 108

Answers (1)

ruddra
ruddra

Reputation: 51968

I am assuming the problem you are facing is that you are using a function in a different file to pull some configuration data in settings, and inside that file you are importing the settings as well. In ideal case, it should trigger circular dependency error. But as django.conf.settings is lazy, it will raise Improper Configuration Error.

If you need some variables for configuration, why don't you pass the variable to the function directly. For example:

# in settings:

from project.utils.providers import AProvider, BProvider, CProvider
SOME_VARIABLE = AProvider(token="Your Token")

Then inside providers

class AProvider(...):
   def __init__(self, *args, **kwargs):
        token = kwargs.get('token')
        # rest of the code

  # somewhere in the code
  fw = get_firewall_instance(self.token)

In firewall.py:

def get_firewall_instance(token_from_settings):

     token = token_from_settings

Upvotes: 1

Related Questions