How to manage local vs production settings in Django?

前端 未结 22 1507
别跟我提以往
别跟我提以往 2020-11-22 15:00

What is the recommended way of handling settings for local development and the production server? Some of them (like constants, etc) can be changed/accessed in both, but s

相关标签:
22条回答
  • 2020-11-22 15:10

    I manage my configurations with the help of django-split-settings.

    It is a drop-in replacement for the default settings. It is simple, yet configurable. And refactoring of your exisitng settings is not required.

    Here's a small example (file example/settings/__init__.py):

    from split_settings.tools import optional, include
    import os
    
    if os.environ['DJANGO_SETTINGS_MODULE'] == 'example.settings':
        include(
            'components/default.py',
            'components/database.py',
            # This file may be missing:
            optional('local_settings.py'),
    
            scope=globals()
        )
    

    That's it.

    Update

    I wrote a blog post about managing django's settings with django-split-sttings. Have a look!

    0 讨论(0)
  • 2020-11-22 15:11

    1 - Create a new folder inside your app and name settings to it.

    2 - Now create a new __init__.py file in it and inside it write

    from .base import *
    
    try:
        from .local import *
    except:
        pass
    
    try:
        from .production import *
    except:
        pass
    

    3 - Create three new files in the settings folder name local.py and production.py and base.py.

    4 - Inside base.py, copy all the content of previous settings.py folder and rename it with something different, let's say old_settings.py.

    5 - In base.py change your BASE_DIR path to point to your new path of setting

    Old path-> BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    New path -> BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    This way, the project dir can be structured and can be manageable among production and local development.

    0 讨论(0)
  • 2020-11-22 15:15

    Making multiple versions of settings.py is an anti pattern for 12 Factor App methodology. use python-decouple or django-environ instead.

    0 讨论(0)
  • 2020-11-22 15:18

    I use a variation of what jpartogi mentioned above, that I find a little shorter:

    import platform
    from django.core.management import execute_manager 
    
    computername = platform.node()
    
    try:
      settings = __import__(computername + '_settings')
    except ImportError: 
      import sys
      sys.stderr.write("Error: Can't find the file '%r_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % (computername, __file__))
      sys.exit(1)
    
    if __name__ == "__main__":
      execute_manager(settings)
    

    Basically on each computer (development or production) I have the appropriate hostname_settings.py file that gets dynamically loaded.

    0 讨论(0)
  • 2020-11-22 15:18

    I differentiate it in manage.py and created two separate settings file: local_settings.py and prod_settings.py.

    In manage.py I check whether the server is local server or production server. If it is a local server it would load up local_settings.py and it is a production server it would load up prod_settings.py. Basically this is how it would look like:

    #!/usr/bin/env python
    import sys
    import socket
    from django.core.management import execute_manager 
    
    ipaddress = socket.gethostbyname( socket.gethostname() )
    if ipaddress == '127.0.0.1':
        try:
            import local_settings # Assumed to be in the same directory.
            settings = local_settings
        except ImportError:
            import sys
            sys.stderr.write("Error: Can't find the file 'local_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
            sys.exit(1)
    else:
        try:
            import prod_settings # Assumed to be in the same directory.
            settings = prod_settings    
        except ImportError:
            import sys
            sys.stderr.write("Error: Can't find the file 'prod_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file prod_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
            sys.exit(1)
    
    if __name__ == "__main__":
        execute_manager(settings)
    

    I found it to be easier to separate the settings file into two separate file instead of doing lots of ifs inside the settings file.

    0 讨论(0)
  • 2020-11-22 15:19

    I use a slightly modified version of the "if DEBUG" style of settings that Harper Shelby posted. Obviously depending on the environment (win/linux/etc.) the code might need to be tweaked a bit.

    I was in the past using the "if DEBUG" but I found that occasionally I needed to do testing with DEUBG set to False. What I really wanted to distinguish if the environment was production or development, which gave me the freedom to choose the DEBUG level.

    PRODUCTION_SERVERS = ['WEBSERVER1','WEBSERVER2',]
    if os.environ['COMPUTERNAME'] in PRODUCTION_SERVERS:
        PRODUCTION = True
    else:
        PRODUCTION = False
    
    DEBUG = not PRODUCTION
    TEMPLATE_DEBUG = DEBUG
    
    # ...
    
    if PRODUCTION:
        DATABASE_HOST = '192.168.1.1'
    else:
        DATABASE_HOST = 'localhost'
    

    I'd still consider this way of settings a work in progress. I haven't seen any one way to handling Django settings that covered all the bases and at the same time wasn't a total hassle to setup (I'm not down with the 5x settings files methods).

    0 讨论(0)
提交回复
热议问题