How to properly runserver on different settings for Django?

前端 未结 7 870
悲哀的现实
悲哀的现实 2021-02-07 14:42

I have a basic django rest API. I want to separate some of my settings for dev and prod just for organizational purposes. I\'m also just learning about separating environments.

7条回答
  •  北恋
    北恋 (楼主)
    2021-02-07 15:33

    This solution works without extra arguments, and without having to replace/delete files across environments.

    Make settings.py decide which file to load

    Let's assume your Django project is named MyDjangoApp.

    Create the config/ dir in your Django project's root dir, and one .py file per environment, e.g. like this:

    config/
      local.py
      dev.py
      prod.py
    MyDjangoApp/
      settings.py
    

    There is no logical limit to the number of environments, I just added the three I usually have.

    Then, inside MyDjangoApp/settings.py we can add the logic to choose which settings file to load.

    """
    Django settings for MyDjangoApp project.
    """
    
    import os
    
    # Begin: Custom per-env settings
    import socket
    # Use the appropriate logic to understand "where" we're running
    HOST = socket.gethostname() 
    configs = {
        'localhost': 'local', # replace 'localhost' with whatever your machine name is
        'dev.mysite.com': 'dev',
        'www.mysite.com': 'production',
    }
    
    config = 'config.{}'.format(configs[HOST])
    
    settings_module = __import__(config, globals(), locals(), ['MyDjangoApp', ])
    
    try:
        for setting in dir(settings_module):
            # Only fully-uppercase variables are supposed to be settings
            if setting == setting.upper():
                locals()[setting] = getattr(settings_module, setting)
    except Exception:
        # you may ignore this exception, the print() is for debugging purposes 
        print(Exception)
    
    # End: Custom per-env settings
    
    # ... the rest of the common settings go here
    

    Please note: this logic chooses the settings file to load based on the hostname of the server which is running the Django app. It's just an example- you can implement any other logic that works for you.

    Change only what's needed

    The good news is, settings.py can still hold the vast majority of your settings, and the files inside config/ just need to contain the settings that change across your environments, e.g.:

    • DATABASES
    • DEBUG
    • ADMINS
    • LOGGING

    Avoid --settings in the commandline

    You can set the Django settings as a shell environment variable, like this:

    export DJANGO_SETTINGS_MODULE=MyDjangoApp.settings
    

    The best place to do this is in a .sh file; usually I create a file named env.sh file in the root dir of the Django project, and run it (once) just after activating the virtualenv.

    File /env.sh contents

    #!/usr/bin/env bash
    
    export DJANGO_SETTINGS_MODULE=MyDjangoApp.settings
    

    To run it from Terminal (Bash, or git-scm Bash on Windows):

    . env.sh 
    

    Then you can use ./manage.py runserver to start the Django server wherever you are.

    Reference: https://code.djangoproject.com/wiki/SplitSettings#DevelopmentMachineDependantSettingsConfiguration

提交回复
热议问题