问题描述:

I have a Django project where I have multiple settings file which has lot of redundant data. The structure is as follows

development.py

app_one = 'http://localhost:8000'

app_two = 'http://localhost:9999'

abc_url = '{0}/some-url/'.format(app_one)

xyz_url = '{0}/some-url/'.format(app_two)

staging.py

app_one = 'http://staging.xyz.abc.com'

app_two = 'http://staging.pqr.abc.com'

abc_url = '{0}/some-url/'.format(app_one)

xyz_url = '{0}/some-url/'.format(app_two)

production.py

app_one = 'http://production.xyz.abc.com'

app_two = 'http://production.pqr.abc.com'

abc_url = '{0}/some-url/'.format(app_one)

xyz_url = '{0}/some-url/'.format(app_two)

In all the files abc_url and xyz_url are basically same url. The only thing that changes is the domain.

What I am looking to is,

  • Put all urls in separate file called app_one_urls.py and app_two_urls.py
  • Find a way to include this app_one_urls.py and app_two_urls.py in my development, staging and productions file

The final outcome can be as follows:

app_one_urls.py

abc_url = '{0}/some-url/'.format(app_one)

app_two_urls.py

xyz_url = '{0}/some-url/'.format(app_two)

are two separate files

in development.py I intend to do following

app_one = 'http://localhost:8000'

app_two = 'http://localhost:9999'

somehow get urls from app_one_urls and app_two_urls

Is it possible and feasible? If yes, I need help in understanding how.

网友答案:

There is no need to maintain separate files, you can define the configuration in dictionary, with key based on the environment type.

Here I am demonstrating based on hostname, as hostnames of my server differs like: my-host-prod, my-host-staging, my-host-dev. You may use the condition which uniquely defines your server.

import socket

def get_url_conf(my_host=socket.gethostname()):
    def get_conf_setting(env_type):
        return {'prod':    {'app1': 'app1_prod_url',
                            'app2': 'app2_prod_url'},
                'staging': {'app1': 'app1_staging_url',
                            'app2': 'app2_staging_url'},
                'dev':     {'app1': 'app1_dev_url',
                            'app2': 'app2_dev_url'},
                'local':   {'app1': 'app1_local_url',
                            'app2': 'app2_local_url'}
                }[env_type]
    if my_host.endswith('-prod'):
        server_key = 'prod'
    elif my_host.endswith('-staging'):
        server_key = 'prod'
    elif my_host.endswith('-dev'):
        server_key = 'dev'
    else:  # In case someone is running on local system
        server_key = 'local'
    return get_conf_setting(server_key)

Now in your settings file, you may call these as:

abc_url = '{0}/some-url/'.format(get_url_conf()[`app1`])
xyz_url = '{0}/some-url/'.format(get_url_conf()[`app2`]) 
网友答案:

Yes, this is feasible. You will need to arrange your settings as a module:

settings/
        /__init__.py
        /development.py
        /staging.py
        /production.py
        /base.py

Contents of base.py :

SOME_ENVIRONMENT_INDEPENDENT_SETTING = 1

Contents of development.py:

from base import *
SOME_DEVELOPMENT_SETTING = 1
app_one = 'http://localhost:8000'
app_two = 'http://localhost:9999'

Content of production.py:

    from base import *
    SOME_PRODUCTION_SETTING = 1
    app_one = 'http://production.xyz.abc.com'
    app_two = 'http://production.pqr.abc.com'

Content of __init__.py:

import os
#If you want to pull environment from an environment variable

#ENVIRONMENT = os.environ.get('CURR_ENV','PROD') 

ENVIRONMENT = "DEVELOPMENT"

if ENVIRONMENT == "PRODUCTION" :
    try:
        from production import *
    except:
        pass

elif ENVIRONMENT == "DEVELOPMENT" :
    try:
        from development import *
    except:
        pass

elif ENVIRONMENT == "STAGING":
    try:
        from staging import *
    except:
        pass

elif ENVIRONMENT.lower() == "DEVEL_LOCAL".lower():
    try:
        from devel_local import *
    except:
        pass

elif ENVIRONMENT.lower() == "PROD_PP".lower():
    try:
        from prod_pp import *
    except:
        pass


#common variables which change based on environment
abc_url = '{0}/some-url/'.format(app_one)
xyz_url = '{0}/some-url/'.format(app_two)
相关阅读:
Top