Django Local Settings

2020-01-25 12:53发布

I'm trying to use local_setting in Django 1.2, but it's not working for me. At the moment I'm just adding local_settings.py to my project.

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco1',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

local_settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco2',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

The problem is that local_settings.py doesn't override settings.py. What is wrong?

8条回答
SAY GOODBYE
2楼-- · 2020-01-25 13:26

This is the best practice I think:

  • local_settings imports from settings
  • local_settings overrides settings specific to the local environment, especially DATABASES, SECRET_KEY, ALLOWED_HOSTS and DEBUG variables
  • pass to django management commands the flag --settings=local_settings

You could implement local_settings like this:

from settings import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco2',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

A few additional key points:

  • settings.py is in version control, written in a way such that it's ready to use by contributors
  • local_settings.py (or more commonly prod_settings.py) is NOT in version control, and used in production by specifying --settings=prod_settings or similar.

Touching the stock settings file as little as possible also makes it easier to upgrade your django version. When you upgrade Django to the next version, look at the diff in the stock settings.py and yours, and take actions as necessary depending on what changed. Changes in the default values can be important, and the less you touched the original settings.py file, the easier it will be to discern upstream changes.

查看更多
贪生不怕死
3楼-- · 2020-01-25 13:29

Add this to the end of the file settings.py

try:
    from .local_settings import *
except ImportError:
    pass

And create file local_settings.py with your new settings for example

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco2',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}
查看更多
爷的心禁止访问
4楼-- · 2020-01-25 13:31

Before running the server do

export DJANGO_SETTINGS_MODULE=your_app_name.local_settings where your_app_name should be replaced by your App's name. And don't forget to do

from settings import *

in your local_settings.py file

查看更多
Bombasti
5楼-- · 2020-01-25 13:32

You can't just add local_settings.py, you have to explicity import it.

At the very end of your settings.py, add this:

try:
    from local_settings import *
except ImportError:
    pass

The try/except block is there so that Python just ignores the case when you haven't actually defined a local_settings file.

查看更多
ら.Afraid
6楼-- · 2020-01-25 13:36

I kept a copy of __local_settings.py:

  • local_settings.py is being ignored in the version control, but not __local_settings.py
  • update README.md to inform the team on how to setup: cp {__,}local_settings.py (which make a copy for their local_settings)

In the past

I used to import those settings.

# settings.py
DATABASE = {...}

try:
    from .local_settings import *
except ImportError:
    pass

now

I just import the settings itself from the local_settings.py.

And with the following command: python manage.py runserver --settings=<proj>.local_settings.

# local_settings.py & __local_settings.py
from .settings import *

DATABASE = {...}

And since, I usually don't interact with manage.py directly, because some parameters are explicitly necessary for me, (e.g. address:port). Therefore, I put all of those command into my Makefile.

For example, here's my Makefile:

run:
    python manage.py runserver 0.0.0.0:8000 --settings=<proj>.local_settings

sh:
    python manage.py shell_plus --settings=<proj>.local_settings

dep:
    npm install
    pip install -r requirements.txt

Thus:

make dep
make sh 
make run

Conclusion

Provided that you are not using Makefile as your workflow, then you may use the earlier method, but if you are using makefile, then i believe it is better to be more explicit in your Makefile.

查看更多
\"骚年 ilove
7楼-- · 2020-01-25 13:42

Yet another approach is to use python-dotenv and environment variables to customize settings for different environments.

Create the .env file along-side your settings.py:

# .env
SECRET_KEY=your-secret-key
DATABASE_PASSWORD=your-database-password

Add the following code to your settings.py:

# settings.py
from dotenv import load_dotenv
load_dotenv()

# OR, explicitly providing path to '.env'
from pathlib import Path  # python 3.4+
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

At this point, parsed keys/values from the .env file are present as environment variables and they can be conveniently accessed via os.getenv():

# settings.py
import os
SECRET_KEY = os.getenv('SECRET_KEY')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')   
查看更多
登录 后发表回答