Load Django settings from a TOML file
dj-toml-settings
reads settings from a TOML file. By default, both pyproject.toml
and django.toml
files are parsed for settings in the [tool.django]
namespace.
[tool.django]
# Paths are relative to the TOML file (unless they are absolute)
BASE_DIR = { "$path" = "." }
STATIC_ROOT = { "$path" = "staticfiles" }
# This sets the key based on the environment variable
SECRET_KEY = { "$env" = "SECRET_KEY" }
# This sets the key based on the environment variable, but has a fallback
ADMIN_URL_PATH = { "$env" = "ADMIN_URL_PATH", "$default"="admin" }
# Booleans, arrays, tables (dictionaries), integers, strings, floats, dates are all supported in TOML
DEBUG = true
ALLOWED_HOSTS = [
"127.0.0.1",
]
# Values can be casted to a bool, int, str, float, decimal, datetime, date, time, timedelta, url, Path
SITE_ID = { "$value" = "1", "$type" = "int" }
# This is an implicit dictionary and equivalent to `COLTRANE = { TITLE = "Example blog" }`
[tool.django.COLTRANE]
TITLE = "Example blog"
# Any name can be used under `apps` for organizational purposes
[tool.django.apps.tailwind-cli]
TAILWIND_CLI_USE_DAISY_UI = true
TAILWIND_CLI_SRC_CSS = ".django_tailwind_cli/source.css"
# These settings are included when the `ENVIRONMENT` environment variable is "development"
[tool.django.envs.development]
ALLOWED_HOSTS = { "$insert" = "example.localhost" }
# These settings are included when the `ENVIRONMENT` environment variable is "production"
[tool.django.envs.production]
DEBUG = false
ALLOWED_HOSTS = { "$insert" = "example.com" }
Use ${SOME_VARIABLE_NAME}
to use an existing setting as a value.
[tool.django]
GOOD_IPS = ["127.0.0.1"]
ALLOWED_HOSTS = "${GOOD_IPS}" # this needs to be quoted to be valid TOML, but will be converted into a `list`
[tool.django.apps.{ANY_NAME_HERE}]
sections of the TOML file can be used to group settings together. They can be named anything. They will override any settings in [tool.django]
.
[tool.django.apps.tailwind-cli]
TAILWIND_CLI_USE_DAISY_UI = true
TAILWIND_CLI_SRC_CSS = ".django_tailwind_cli/source.css"
The [tool.django.envs.{ENVIRONMENT_NAME}]
section of the TOML file will be used when {ENVIRONMENT_NAME}
is set to the ENVIRONMENT
environment variable. For example, ENVIRONMENT=production python manage.py runserver
will load all settings in the [tool.django.envs.production]
section. There settings will override any settings in [tool.django.apps.*]
or [tool.django]
.
[tool.django]
ALLOWED_HOSTS = ["127.0.0.1"]
[tool.django.envs.development]
ALLOWED_HOSTS = ["example.localhost"]
[tool.django.envs.production]
ALLOWED_HOSTS = ["example.com"]
By default, special operations are denoted by an inline table
, (aka a dictionary
) with a key that starts with a $
, e.g. { "$value" = "1" }
.
Converts a string to a Path
object by using a $path
key. Handles relative paths based on the location of the parsed TOML file.
[tool.django]
BASE_DIR = { "$path" = "." }
PROJECT_DIR = { "$path" = "./your_project_folder" }
REPOSITORY_DIR = { "$path" = "./.." }
Retrieve variables from the environment by using an $env
key. Specify an optional $default
key for a fallback value.
[tool.django]
EMAIL_HOST_PASSWORD = { "$env" = "SECRET_PASSWORD" }
SECRET_KEY = { "$env" = "SECRET_KEY", "$default" = "this-is-a-secret" }
Add items to an array by using the $insert
key.
[tool.django]
ALLOWED_HOSTS = { "$insert" = "127.0.0.1" }
Specify the index of the new item with the $index
key.
[tool.django]
ALLOWED_HOSTS = { "$insert" = "127.0.0.1", "$index" = 0 }
Specify None
for a variable with a $none
key. The value must be truthy, i.e. true
or 1 (even though the value won't get used).
[tool.django]
EMAIL_HOST_PASSWORD = { "$none" = 1 }
Specifies a value for a variable.
[tool.django]
SITE_ID = { "$value" = 1 }
Casts the value to a particular type. Supported types: bool
, int
, str
, float
, decimal
, datetime
, date
, time
, timedelta
, url
, and Path
. Especially helpful for values that come from environment variables which are usually read in as strings.
$type
can be used as an additional operator with any other operator.
[tool.django]
SITE_ID = { "$env" = "SITE_ID", $type = "int" }
[tool.django]
SITE_ID = { "$value" = "1", $type = "int" }
This will override any variables defined in settings.py
with settings from the TOML files.
# settings.py
from pathlib import Path
from dj_toml_settings import configure_toml_settings
BASE_DIR = Path(__file__).resolve().parent.parent
...
configure_toml_settings(base_dir=BASE_DIR, data=globals())
# app.py
from pathlib import Path
from dj_toml_settings import get_toml_settings
base_dir = Path(__file__).resolve().parent
app = Django(**get_toml_settings(base_dir=base_dir))
...
# app.py
from pathlib import Path
from django.core.management import execute_from_command_line
from dj_toml_settings import get_toml_settings
from coltrane import initialize
base_dir = Path(__file__).resolve().parent.parent
wsgi = initialize(**get_toml_settings(base_dir=base_dir))
if __name__ == "__main__":
execute_from_command_line()
...
This is the order that files and sections are parsed (by default). The later sections override the previous settings.
pyproject.toml
->[tool.django]
pyproject.toml
->[tool.django.apps.*]
pyproject.toml
->[tool.django.envs.*]
that matchENVIRONMENT
environment variabledjango.toml
->[tool.django]
django.toml
->[tool.django.apps.*]
django.toml
->[tool.django.envs.*]
that matchENVIRONMENT
environment variable
from pathlib import Path
from dj_toml_settings import get_toml_settings
base_dir = Path(__file__).resolve().parent
toml_settings = get_toml_settings(base_dir=base_dir, toml_settings_files=["custom-settings.toml"])
...
uv install pip install -e .[dev]
just test