Changeset - 3826b6fb66e7
[Not reviewed]
1 6 4
Ben Sturmfels (bsturmfels) - 1 month ago 2024-03-20 03:10:00
ben@sturm.com.au
Switch settings to use "the one true way" approach

The advantage of this approach is that the production and dev configurations are
in version control, so there's less opportunity for surprises.

As advocated by Jacob Kaplan-Moss (OSCON 2011) and Two Scoops of Django book.
10 files changed with 65 insertions and 16 deletions:
0 comments (0 inline, 0 general)
.gitignore
Show inline comments
...
 
@@ -4,6 +4,7 @@ __pycache__
 
conservancy/djangocommonsettings.py
 
conservancy/static/docs/Transcript_Full_Vizios_MSJ_HearingDeptC-33.231005.pdf
 
conservancy/static/docs/SFC_response_to_summary_judgement.pdf
 
conservancy/static/docs/Vizio_summary_judgement_reply_brief.pdf
 
conservancy/static/docs/2023-4-28 VIZIOs Motion for Summary Judgment with Reservation.pdf
 

	
 
/conservancy/secrets.json
Dockerfile-debian-bookworm
Show inline comments
 
# To build the Docker image with the necessary dependencies:
 
# docker build --tag sfconservancy.org-bookworm --file Dockerfile-debian-bookworm .
 
#
 
# To run the website, first ensure you have a
 
# "conservancy/djangocommonsettings.py" file, with an appropriate database path.
 
#
 
# [FIRST RUN ONLY] If you don't have an existing copy of the database, run:
 
# touch conservancy-website.sqlite3
 
#
 
# Start the application with:
 
# docker run --tty --interactive --rm=true --publish=8000:8000 \
 
#   --mount type=bind,source=$(pwd),target=/var/www/website \
README.md
Show inline comments
...
 
@@ -35,16 +35,12 @@ exist** on disk for the redirect to be applied.
 

	
 
Python dependencies in `requirements.txt` are tied to the versions available in
 
Debian:
 

	
 
    python3 -m pip install -r requirements.txt
 

	
 
You'll need a copy of `conservancy/djangocommonsettings.py`, a file that not
 
committed to the repository that has database settings and other
 
environment-specific config.
 

	
 
To run the tests, install `pytest-django` and run pytest:
 

	
 
    python3 -m pip install pytest-django
 
    python3 -m pytest
 

	
 
Then run:
TODO.md
Show inline comments
...
 
@@ -2,18 +2,18 @@
 

	
 
* remove `ForceCanonicalHostnameMiddleware` by ensuring canonical redirect and HTTPS redirect is done by Apache
 
* serve a 400 in Apache for a hostname we don't explicitly support
 
* use `<detail>` elements for supporter page hidden sections, rather than complex jQuery - or consider Alpine.js
 
* replace `internalNavigate` with inline flexbox layout
 
* add tests for main pages returning 200
 
* standardise settings to replace `settings.py` and `djangocommonsettings.py`
 
  with `settings/prod.py` and move `SECRET_KEY` to an environment variable
 

	
 

	
 
# Done
 

	
 
* standardise settings to replace `settings.py` and `djangocommonsettings.py`
 
  with `settings/prod.py` and move `SECRET_KEY` to an environment variable
 
* migrate to Django 4.2 LTS
 
* review `apache2` directory - may be unused
 
* add deployment script that runs migrations and collects static files
 
* switch `ParameterValidator` to use `SECRET_KEY` if possible to minimize
 
  non-standard settings
 
* install staticfiles app
conservancy/local_context_processors.py
Show inline comments
 
from datetime import datetime as DateTime
 

	
 
from . import settings
 
from django.conf import settings
 

	
 
from .fundgoal.models import FundraisingGoal
 

	
 
SITE_FUNDGOAL = 'cy2023-end-year-match'
 

	
 
def fundgoal_lookup(fundraiser_sought):
 
    try:
conservancy/settings/__init__.py
Show inline comments
 
new file 100644
conservancy/settings/base.py
Show inline comments
 
file renamed from conservancy/settings.py to conservancy/settings/base.py
...
 
@@ -16,19 +16,15 @@
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program in a file in the toplevel directory called
 
# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from pathlib import Path
 

	
 
from .djangocommonsettings import *
 

	
 
SITE_ID = 2
 
ROOT_URLCONF = 'conservancy.urls'
 

	
 
FORCE_CANONICAL_HOSTNAME = False if DEBUG else 'sfconservancy.org'
 

	
 
REDIRECT_TABLE = {
 
    'www.sf-conservancy.org': 'sfconservancy.org',
 
}
 

	
 
LOGGING = {
 
    'version': 1,
...
 
@@ -98,13 +94,13 @@ INSTALLED_APPS = [
 
    'conservancy.podjango',
 
    'conservancy.usethesource.apps.UseTheSourceConfig',
 
]
 

	
 
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
 

	
 
BASE_DIR = Path(__file__).resolve().parent
 
BASE_DIR = Path(__file__).resolve().parent.parent
 
TEMPLATES = [
 
    {
 
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
 
        'DIRS': [
 
            BASE_DIR / 'templates',
 
            BASE_DIR / 'static',
conservancy/settings/dev.py
Show inline comments
 
new file 100644
 
from .base import *
 

	
 
DEBUG = True
 
ALLOWED_HOSTS = ['*']
 

	
 
FORCE_CANONICAL_HOSTNAME = False
 

	
 
DATABASES = {
 
    'default': {
 
        'NAME': 'conservancy-website.sqlite3',
 
        'ENGINE': 'django.db.backends.sqlite3',
 
    }
 
}
 

	
 
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
 

	
 
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
conservancy/settings/prod.py
Show inline comments
 
new file 100644
 
import json
 

	
 
from django.core.exceptions import ImproperlyConfigured
 

	
 
from .base import *
 

	
 
DEBUG = False
 
ALLOWED_HOSTS = ['www.sfconservancy.org', 'sfconservancy.org']
 

	
 
FORCE_CANONICAL_HOSTNAME = 'sfconservancy.org'
 

	
 
ADMINS = [
 
    ('Bradley M. Kuhn', 'sysadmin@sfconservancy.org'),
 
    ('Ben Sturmfels', 'sysadmin+conservancy@sturm.com.au'),
 
]
 

	
 
MANAGERS = [
 
    ('Bradley M. Kuhn', 'sysadmin@sfconservancy.org'),
 
]
 

	
 
DATABASES = {
 
    'default': {
 
        'NAME': '/var/lib/www/database/conservancy-website.sqlite3',
 
        'ENGINE': 'django.db.backends.sqlite3',
 
    }
 
}
 

	
 
# Apache/mod_wsgi doesn't make it straightforward to pass environment variables
 
# to Django (can't use the Apache config).
 
with open(BASE_DIR / 'secrets.json') as f:
 
    secrets = json.load(f)
 

	
 
def get_secret(secrets, setting):
 
    try:
 
        return secrets[setting]
 
    except KeyError:
 
        raise ImproperlyConfigured(f'Missing secret \'{setting}\'')
 

	
 
SECRET_KEY = get_secret(secrets, 'SECRET_KEY')
 

	
 
SESSION_COOKIE_SECURE = True
manage.py
Show inline comments
...
 
@@ -4,13 +4,13 @@
 
See https://docs.djangoproject.com/en/4.0/ref/django-admin/
 
"""
 
import os
 
import sys
 

	
 
if __name__ == '__main__':
 
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conservancy.settings')
 
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conservancy.settings.dev')
 
    try:
 
        from django.core.management import execute_from_command_line
 
    except ImportError as exc:
 
        raise ImportError(
 
            "Couldn't import Django. Are you sure it's installed and "
 
            "available on your PYTHONPATH environment variable? Did you "
0 comments (0 inline, 0 general)