W pierwszej części omówiliśmy krótki setup projektu obejmujący środowisko Python oraz repozytorium kodu.
W tej części zajmiemy się wstępną konfiguracją aplikacji Django oraz uruchomieniem panelu administracyjnego.
Repozytorium kodu dostępne jest na platformie GitHub.
Konfiguracja ustawień aplikacji (django settings)
Defaults
Tworzę pakiet "settings":
$ mkdir -v vmapp/vmapp/settings
Następnie przenoszę domyślnie wygenerowany plik settings.py do tego pakietu, jako moduł "defaults.py".
$ mv vmapp/vmapp/settings.py vmapp/vmapp/settings/defaults.py
Konfigurację bazy danych ustawiam na:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.environ.get("SQLITE_DB_PATH", ":memory:")
}
}
Domyślnie baza danych umieszczona jest w pamięci, zatem uruchomienie aplikacji w innym trybie wymagać będzie poprawnej konfiguracji, którą przekażę za pomocą zmiennych środowiskowych.
Development / Testing
Tworzę pliki vmapp/vmapp/settings/development.py i vmapp/vmapp/settings/testing.py o identycznej zawartości:
import os
from .defaults import * # noqa: 401
DEBUG = True
Production
Tworzę plik vmapp/vmapp/settings/production.py.
import os
from .defaults import * # noqa: 401
DEBUG = False
ALLOWED_HOSTS = ["127.0.0.1"]
SECRET_KEY = os.environ.get("SECRET_KEY", "change-this")
W środowisku produkcyjnym DEBUG ustawiam na False, a zmienna SQLITE_DB_PATH będzie zawsze musiała zostać podana przy uruchomieniu aplikacji. Dodatkowo ustawiam ALLOWED_HOSTS, w tej chwili na localhost.
Próba standardowego uruchomienia aplikacji zakończy się w tej chwili niepowodzeniem, gdyż Django w defaults.py ma ustawione DEBUG = False, a ALLOWED_HOSTS na pustą listę.
$ python vmapp/manage.py runserver
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
Konfiguracja środowisk (.env/*)
Tworzę katalog .env, w którym umieszczę pliki ze zmiennymi środowiskowymi poszczególnych konfiguracji.
$ mkdir .env
W każdym z tych plików umieszczam odpowiednią konfigurację (DJANGO_SETTINGS_MODULE, SQLITE_DB_PATH).
.env/development
DJANGO_SETTINGS_MODULE='vmapp.settings.development'
SQLITE_DB_PATH='.ignore/development.sqlite3'
.env/testing
DJANGO_SETTINGS_MODULE='vmapp.settings.testing'
SQLITE_DB_PATH=':memory:'
.env/production
DJANGO_SETTINGS_MODULE='vmapp.settings.production'
SQLITE_DB_PATH='/srv/vmapp/db/vmapp.db'
Temat zmiennych środowiskowych i ich bezpieczeństwa w systemach operacyjnych, dockerze (compose, secrets w docker swarm, itd.) zostawię na inną okazję.
Skrypt uruchamiający aplikację
Tworzę teraz prosty skrypt shell, którego używał będę do uruchamiania aplikacji z ustawieniami żądanego środowiska.
Skrypt znajduje się w głównym katalogu projektu, ładuje dane środowisko, a następnie uruchamia skrypt manage.py z Django.
#!/bin/sh
set -e
set -u
ENV=${1:-development}
test $# -gt 0 && shift || true
. .env/$ENV
DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE} \
SQLITE_DB_PATH=${SQLITE_DB_PATH} \
python3 vmapp/manage.py $@
Nadaję mu uprawnienia do wykonywania:
$ chmod a+x manage
Uruchomienie aplikacji
Skrypt manage domyślnie ustawia środowisko development. Jako pierwszy (w tej chwili jedyny) argument możemy przekazać nazwę środowiska.
$ ./manage
$ ./manage development
$ ./manage testing
$ ./manage production
Pozostałe argumenty trafiają bezpośrednio do skryptu manage.py z django.
Do uruchomienia aplikacji w trybie development muszę jeszcze utworzyć katalog ".ignore", w którym ma się znaleźć plik bazy danych (wskazany zmienną środowiskowa SQLITE_DB_PATH):
$ mkdir .ignore/
Wykonuję teraz migrację:
$ ./manage development migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
Tworzę konto administratora:
$ ./manage development createsuperuser --username admin --email admin@localhost
Password:
Password (again):
Superuser created successfully.
Uruchamiam serwer deweloperski:
$ ./manage development runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
December 11, 2021 - 11:21:43
Django version 4.0, using settings 'vmapp.settings.development'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
I loguję się do panelu administracyjnego:
$ firefox http://127.0.0.1:8000/admin/
W następnej części zajmiemy się tworzeniem modeli dla systemu pocztowego oraz testami jednostkowymi.