Skip to content

Commit 2d2d280

Browse files
committed
WIP
1 parent d6378b7 commit 2d2d280

File tree

4 files changed

+115
-35
lines changed

4 files changed

+115
-35
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
**/.venv
22
*console.log
33
.coverage
4-
.env
4+
.env*
55
.idea/
66
.mypy_cache/**/*
77
.pytest_cache/**/*

config/settings/_base.py

Lines changed: 99 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,71 @@
11
import contextlib
22
import socket
3+
from functools import partial
4+
from pathlib import Path
35

4-
import environs
6+
from django.utils.crypto import get_random_string
57

6-
env = environs.Env()
8+
from django_envtools import Env
79

810
"""
911
Django settings for config project.
1012
1113
For more information on this file, see
12-
https://docs.djangoproject.com/en/4.2/topics/settings/
14+
https://docs.djangoproject.com/en/dev/topics/settings/
1315
1416
For the full list of settings and their values, see
15-
https://docs.djangoproject.com/en/4.2/ref/settings/
17+
https://docs.djangoproject.com/en/dev/ref/settings/
1618
"""
1719

18-
BASE_DIR = environs.Path(__file__).parent.parent.parent # type: ignore
20+
21+
get_secret_key = partial(get_random_string, length=50, allowed_chars="abcdefghijklmnopqrstuvwxyz0123456789!@%^&*-_=")
22+
23+
24+
BASE_DIR = Path(__file__).parent.parent.parent # type: ignore
25+
26+
env = Env()
1927

2028
READ_DOT_ENV_FILE = env.bool("READ_DOT_ENV_FILE", default=True)
2129

2230
if READ_DOT_ENV_FILE is True:
2331
env.read_env(str(BASE_DIR.joinpath(".env")))
2432

2533
# Quick-start development settings - unsuitable for production
26-
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
34+
# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
2735

2836
# SECURITY WARNING: keep the secret key used in production secret!
29-
SECRET_KEY = env("SECRET_KEY")
37+
SECRET_KEY = env.str(
38+
"SECRET_KEY",
39+
help_text="Django's secret key, see"
40+
"https://docs.djangoproject.com/en/dev/ref/settings/#secret-key for more information",
41+
initial_func=get_secret_key,
42+
)
3043

3144
# SECURITY WARNING: don't run with debug turned on in production!
32-
DEBUG = env.bool("DEBUG", default=False)
45+
DEBUG = env.bool("DEBUG", default=False, initial="on", help_text="Set to `on` to enable debugging")
46+
47+
ALLOWED_HOSTS = env.list(
48+
"ALLOWED_HOSTS",
49+
default=[],
50+
help_text="List of allowed hosts (e.g., `127.0.0.1,example.com`), see "
51+
"https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts for more information",
52+
)
3353

34-
ALLOWED_HOSTS: list[str] = env.list("ALLOWED_HOSTS", default=[])
35-
INTERNAL_IPS = env.list("INTERNAL_IPS", default=["127.0.0.1"])
54+
INTERNAL_IPS = env.list(
55+
"INTERNAL_IPS",
56+
default=["127.0.0.1"],
57+
initial="127.0.0.1,0.0.0.0",
58+
help_text="IPs that are allowed to use debug() (e.g., `127.0.0.1,example.com`), see "
59+
"https://docs.djangoproject.com/en/dev/ref/settings/#internal-ips for more information",
60+
)
3661

3762
# Get the IP to use for Django Debug Toolbar when developing with docker
38-
if env.bool("USE_DOCKER", default=False) is True:
63+
if (
64+
env.bool(
65+
"USE_DOCKER", default=False, help_text="Boolean used to add docker's internal ip to the `INTERNAL_IPS` setting"
66+
)
67+
is True
68+
):
3969
ip = socket.gethostbyname(socket.gethostname())
4070
INTERNAL_IPS += [ip[:-1] + "1"]
4171

@@ -56,6 +86,7 @@
5686
"allauth.account",
5787
"crispy_forms",
5888
"crispy_bootstrap5",
89+
"django_envtools",
5990
"storages",
6091
]
6192

@@ -92,23 +123,35 @@
92123
},
93124
]
94125

95-
WSGI_APPLICATION = env("WSGI_APPLICATION", default="config.wsgi.application")
96-
DB_SSL_REQUIRED = env.bool("DB_SSL_REQUIRED", default=not DEBUG)
126+
WSGI_APPLICATION = env.str(
127+
"WSGI_APPLICATION",
128+
default="config.wsgi.application",
129+
help_text="WSGI application callable, see https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application for "
130+
"more information",
131+
)
132+
DB_SSL_REQUIRED = env.bool(
133+
"DB_SSL_REQUIRED",
134+
default=not DEBUG,
135+
help_text="Set to `on` to require SSL for database connections, default is `off` when DEBUG is `on`",
136+
)
97137

98-
# Database
99-
# See https://github.com/jacobian/dj-database-url for more examples
100138
DATABASES = {
101139
"default": env.dj_db_url(
102-
"DATABASE_URL", default="postgres://postgres@postgres/postgres", ssl_require=DB_SSL_REQUIRED
140+
"DATABASE_URL",
141+
default="postgres://postgres@postgres/postgres",
142+
ssl_require=DB_SSL_REQUIRED,
143+
initial="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}",
144+
help_text="Database URL for the default database, see https://github.com/jacobian/dj-database-url for "
145+
"more examples",
103146
)
104147
}
105148

106149
# Custom User Model
107-
# https://docs.djangoproject.com/en/4.2/topics/auth/customizing/#substituting-a-custom-user-model
150+
# https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
108151
AUTH_USER_MODEL = "accounts.User"
109152

110153
# Password validation
111-
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
154+
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators
112155

113156
AUTH_PASSWORD_VALIDATORS = [
114157
{
@@ -127,7 +170,7 @@
127170

128171

129172
# Internationalization
130-
# https://docs.djangoproject.com/en/4.2/topics/i18n/
173+
# https://docs.djangoproject.com/en/dev/topics/i18n/
131174

132175
LANGUAGE_CODE = "en-us"
133176

@@ -140,30 +183,42 @@
140183

141184

142185
# Static files (CSS, JavaScript, Images)
143-
# https://docs.djangoproject.com/en/4.2/howto/static-files/
186+
# https://docs.djangoproject.com/en/dev/howto/static-files/
144187

145188
STATICFILES_FINDERS = (
146189
"django.contrib.staticfiles.finders.FileSystemFinder",
147190
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
148191
)
149192

193+
DEFAULT_FILE_STORAGE = env.str(
194+
"DEFAULT_FILE_STORAGE",
195+
default="django.core.files.storage.FileSystemStorage",
196+
help_text="Default file storage backend, see https://docs.djangoproject.com/en/dev/ref/settings/#storages for "
197+
"more information",
198+
)
199+
STATICFILES_STORAGE = env.str(
200+
"DEFAULT_FILE_STORAGE",
201+
default="django.core.files.storage.FileSystemStorage",
202+
help_text="Default file storage for staticfiles, see https://docs.djangoproject.com/en/dev/ref/settings/#storages "
203+
"for more information",
204+
)
150205
STORAGES = {
151206
"default": {
152-
"BACKEND": env("DEFAULT_FILE_STORAGE", default="django.core.files.storage.FileSystemStorage"),
207+
"BACKEND": DEFAULT_FILE_STORAGE,
153208
},
154209
"staticfiles": {
155-
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
210+
"BACKEND": STATICFILES_STORAGE,
156211
},
157212
}
158213

159214

160215
if STORAGES["default"]["BACKEND"].endswith("MediaS3Storage") is True:
161-
STORAGES["staticfiles"]["BACKEND"] = env("STATICFILES_STORAGE")
162-
AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID")
163-
AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY")
164-
AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME")
216+
STORAGES["staticfiles"]["BACKEND"] = STATICFILES_STORAGE
217+
AWS_ACCESS_KEY_ID = env.str("AWS_ACCESS_KEY_ID", help_text="AWS Access Key ID for S3 storage")
218+
AWS_SECRET_ACCESS_KEY = env.str("AWS_SECRET_ACCESS_KEY", help_text="AWS Secret Access Key for S3 storage")
219+
AWS_STORAGE_BUCKET_NAME = env.str("AWS_STORAGE_BUCKET_NAME", help_text="AWS S3 Bucket Name for storage")
165220
AWS_DEFAULT_ACL = "public-read"
166-
AWS_S3_REGION = env("AWS_S3_REGION", default="us-east-2")
221+
AWS_S3_REGION = env.str("AWS_S3_REGION", default="us-east-1", help_text="AWS S3 Region for storage")
167222
AWS_S3_CUSTOM_DOMAIN = f"s3.{AWS_S3_REGION}.amazonaws.com/{AWS_STORAGE_BUCKET_NAME}"
168223
AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
169224
STATIC_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/static/"
@@ -181,13 +236,21 @@
181236
STATIC_URL = "/public/static/"
182237

183238
# Default primary key field type
184-
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
239+
# https://docs.djangoproject.com/en/dev/ref/settings/#default-auto-field
185240
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
186241

187242
# CACHE SETTINGS
188-
# Redis scheme docs: https://redis-py.readthedocs.io/en/stable/connections.html#redis.connection.ConnectionPool.from_url
189-
REDIS_URL = env("REDIS_URL", "redis://redis:6379/0")
190-
REDIS_PREFIX = env("REDIS_PREFIX", default="")
243+
REDIS_URL = env.str(
244+
"REDIS_URL",
245+
default="redis://redis:6379/0",
246+
help_text="URL used to connect to Redis, see https://docs.djangoproject.com/en/dev/ref/settings/#location for "
247+
"more information",
248+
)
249+
REDIS_PREFIX = env.str(
250+
"REDIS_PREFIX",
251+
default="",
252+
help_text="Prefix for all Redis keys, useful to avoid key collisions in shared Redis instances",
253+
)
191254
CACHES = {
192255
"default": {
193256
"BACKEND": "django.core.cache.backends.redis.RedisCache",
@@ -232,10 +295,10 @@
232295
ACCOUNT_SIGNUP_OPEN = False
233296
ACCOUNT_SHOW_POST_LOGIN_MESSAGE = False
234297

235-
# See https://github.com/migonzalvar/dj-email-url for more examples on how to set the EMAIL_URL
236298
email = env.dj_email_url(
237299
"EMAIL_URL",
238300
default="smtp://[email protected]:[email protected]:587/?ssl=True&_default_from_email=President%20Skroob%20%[email protected]%3E",
301+
help_text="Email URL for sending emails, see https://github.com/migonzalvar/dj-email-url for more examples",
239302
)
240303
DEFAULT_FROM_EMAIL = email["DEFAULT_FROM_EMAIL"]
241304
EMAIL_HOST = email["EMAIL_HOST"]
@@ -266,7 +329,7 @@ def log_format() -> str:
266329

267330

268331
log_level = "WARNING"
269-
IS_DEBUG_LOGGING_ON = env.bool("IS_DEBUG_LOGGING_ON", default=False)
332+
IS_DEBUG_LOGGING_ON = env.bool("IS_DEBUG_LOGGING_ON", default=False, help_text="Set to `on` to enable debug logging")
270333
if IS_DEBUG_LOGGING_ON is True:
271334
log_level = "DEBUG"
272335

@@ -305,4 +368,6 @@ def log_format() -> str:
305368
MAINTENANCE_MODE_STATE_BACKEND = "maintenance_mode.backends.CacheBackend"
306369
MAINTENANCE_MODE_STATE_BACKEND_FALLBACK_VALUE = True
307370

308-
VITE_DEV_MODE = env.bool("VITE_DEV_MODE", default=DEBUG)
371+
VITE_DEV_MODE = env.bool(
372+
"VITE_DEV_MODE", default=DEBUG, help_text="Set to `on` to enable Vite development mode for HMR in the browser"
373+
)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies = [
1111
"django-alive~=2.0",
1212
"django-allauth~=65.0",
1313
"django-crispy-forms~=2.2",
14+
"django-envtools~=0.2",
1415
"django-maintenance-mode~=0.19",
1516
"django-storages~=1.8",
1617
"environs[django]~=14.1",

uv.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)