Web-Anwendung zur einfachen Erfassung von (Geo-)Daten, die auf Django aufsetzt
- Voraussetzungen
- Installation
- Konfiguration
- Initialisierung
- Start
- Deployment
- UML-Klassendiagramme
- Hilfe (für Administration und Nutzung)
- Cronjobs
- PDF-Export mit eigenen Templates
- Entwicklung
- Linting
- Tests
- CI/CD
- Python (>=3.13)
- pip
- GDAL
- PostgreSQL mit der Erweiterung PostGIS
- npm
- optional Redis
- optional für App Toolbox siehe hier
- Git-Repository klonen:
git clone https://github.com/rostock/datenwerft
cd datenwerft- neue virtuelle Python-Umgebung anlegen:
# ohne Projektmanagement durch uv
python3 -m venv .venv
# mit Projektmanagement durch uv
uv venv- benötigte Python-Module (unter anderem Django) installieren via pip:
# ohne uv
source .venv/bin/activate
pip install -r datenwerft/requirements.txt
# mit uv
uv sync- leere PostgreSQL-Datenbank für die Anwendungsadministration anlegen
- leere PostgreSQL-Datenbank für die App GDI.HRO Codelists anlegen
- leere PostgreSQL-Datenbank für die App GDI.HRO Metadata anlegen
- leere PostgreSQL-Datenbank mit der Erweiterung PostGIS für die App Antragsmanagement anlegen
- leere PostgreSQL-Datenbank mit der Erweiterung PostGIS für die App BEMAS anlegen
- leere PostgreSQL-Datenbank mit der Erweiterung PostGIS für die App Datenmanagement anlegen
- leere PostgreSQL-Datenbank mit der Erweiterung PostGIS für die App FMM anlegen
- Datenbankschema in Datenbank für die App Datenmanagement installieren (da keines der Datenmodelle in dieser App von Django verwaltet wird):
psql -h [Datenbankhost] -U [Datenbanknutzer] -d [Datenbankname] -f datenmanagement/sql/schema.sql- Konfigurationsdatei auf Basis der entsprechenden Vorlage erstellen:
cp datenwerft/secrets.template datenwerft/secrets.py- Konfigurationsdatei
datenwerft/secrets.pyentsprechend anpassen - Service-Datei für RQ-Worker auf Basis der entsprechenden Vorlage erstellen:
cp rq-worker.service /etc/systemd/system/rq-worker.service- Service-Datei für RQ-Worker entsprechend anpassen
- JavaScript-Module via npm installieren:
npm install- Anwendung initialisieren:
# ohne uv
source .venv/bin/activate
python manage.py migrate --database=antragsmanagement antragsmanagement
python manage.py migrate --database=bemas bemas
python manage.py migrate --database=fmm fmm
python manage.py migrate --database=gdihrocodelists gdihrocodelists
python manage.py migrate --database=gdihrometadata gdihrometadata
python manage.py migrate
python manage.py antragsmanagement_roles_permissions
python manage.py bemas_roles_permissions
python manage.py fmm_roles_permissions
python manage.py gdihrocodelists_roles_permissions
python manage.py gdihrometadata_roles_permissions
python manage.py loaddata --database=gdihrometadata gdihrometadata_initial-data.json
# mit uv
uv run manage.py migrate --database=antragsmanagement antragsmanagement
uv run manage.py migrate --database=bemas bemas
uv run manage.py migrate --database=fmm fmm
uv run manage.py migrate --database=gdihrocodelists gdihrocodelists
uv run manage.py migrate --database=gdihrometadata gdihrometadata
uv run manage.py migrate
uv run manage.py antragsmanagement_roles_permissions
uv run manage.py bemas_roles_permissions
uv run manage.py fmm_roles_permissions
uv run manage.py gdihrocodelists_roles_permissions
uv run manage.py gdihrometadata_roles_permissions
uv run manage.py loaddata --database=gdihrometadata gdihrometadata_initial-data.json- Administrator initialisieren:
# ohne uv
python manage.py createsuperuser
# mit uv
uv run manage.py createsuperuser- statische Dateien initialisieren:
# ohne uv
python manage.py collectstatic -c
# mit uv
uv run manage.py collectstatic -cStart der Anwendung (zum Testen oder während der Entwicklung):
- RQ-Worker starten:
# ohne uv
source .venv/bin/activate
python manage.py rqworker default
# mit uv
uv run manage.py rqworker default- Entwicklungsserver starten:
# ohne uv
python manage.py runserver
# mit uv
uv run manage.py runserverDeployment am Beispiel des Apache HTTP Servers:
- Besitzer und Gruppe des Anwendungsverzeichnisses entsprechend des Apache HTTP Servers anpassen:
sudo chown -R wwwrun:www /path/to/datenwerft- RQ-Worker-Service aktivieren und starten:
sudo systemctl daemon-reload
sudo systemctl enable rq-worker.service
sudo systemctl start rq-worker.service- Wenn das Deployment mittels Apache HTTP Server realisiert werden soll, muss dessen Modul mod_wsgi (für Python 3.x) installiert sein, das ein Web Server Gateway Interface (WSGI) für das Hosting von Python-Anwendungen zur Verfügung stellt.
- Konfigurationsdatei des Apache HTTP Servers öffnen und in etwa folgenden Inhalt einfügen (in diesem Beispiel nutzt die virtuelle Python-Umgebung einen Python-Interpreter der Version 3.x):
Alias /datenwerft/static /path/to/datenwerft/datenwerft/static
Alias /datenwerft/uploads /path/to/datenwerft/datenwerft/uploads
WSGIDaemonProcess datenwerft processes=[Anzahl CPU x 2] threads=[Anzahl GB RAM x 3] connect-timeout=150 deadlock-timeout=300 eviction-timeout=0 graceful-timeout=150 inactivity-timeout=300 queue-timeout=300 request-timeout=300 shutdown-timeout=5 socket-timeout=300 startup-timeout=15 restart-interval=0 python-path=/path/to/datenwerft:/path/to/datenwerft/.venv/lib64/python3.1x/site-packages:/path/to/datenwerft/.venv/lib/python3.1x/site-packages
WSGIProcessGroup datenwerft
WSGIScriptAlias /datenwerft /path/to/datenwerft/datenwerft/wsgi.py process-group=datenwerft
WSGIApplicationGroup %{GLOBAL}
<Directory /path/to/datenwerft/datenwerft>
<Files wsgi.py>
Order deny,allow
Require all granted
</Files>
</Directory>
<Directory /path/to/datenwerft/static>
Order deny,allow
Require all granted
</Directory>
<Directory /path/to/datenwerft/uploads>
Order deny,allow
Require all granted
</Directory>Für die Visualisierung der nachfolgend verlinkten UML-Klassendiagramme kann zum Beispiel dieses Online-Tool genutzt werden.
Klassenstruktur als UML-Diagramm siehe PlantUML-Datei
Klassenstruktur als UML-Diagramm siehe PlantUML-Datei
Klassenstruktur als UML-Diagramm siehe PlantUML-Datei
Klassenstruktur als UML-Diagramm siehe PlantUML-Datei
Klassenstruktur als UML-Diagramm siehe PlantUML-Datei
Für die App BEMAS kann optional ein Cronjob eingerichtet werden, der folgenden Befehl ausführt:
# ohne uv
source .venv/bin/activate
python manage.py deletepersons
# mit uv
uv run manage.py deletepersonsZum Hintergrund dieses Befehls siehe hier.
Für den Export von PDF-Dateien mit eigenen Templates aus der App Datenmanagement mittels der App Toolbox siehe hier.
Bei Einrückungen werden generell zwei Leerzeichen verwendet, bei Umbrucheinrückungen vier.
Der Python-Code orientiert sich an der Python-Styling-Konvention PEP8. Es empfiehlt sich ein Tool wie ruff zur Überprüfung des Codes zu nutzen.
Die Python-Dokumentation wird mittels Docstrings in reStructuredText geschrieben.
Nützliche Tools für eine Entwicklungsumgebung, wie etwa ruff, können zusätzlich via pip installiert werden:
# ohne uv
source .venv/bin/activate
pip install -r requirements-dev.txt
# mit uv
uv sync --devDie Vorgaben von PEP8 finden mit zwei Ausnahmen vollständig Anwendung:
- Zeilenlänge wird von 79 auf 99 erhöht
- Anzahl der Leerzeichen bei der Einrückung wird von vier auf zwei reduziert (ergibt zudem eine Umbrucheinrückung von vier statt acht)
Die entsprechende Konfigurationsdatei pyproject.toml für (zum Beispiel) ruff ist bereits im Wurzelverzeichnis des Projekts angelegt.
JavaScript-Funktionen werden mittels JSDoc dokumentiert, angelehnt an diese Übersicht.
pg_dump -U [Datenbanknutzer] -O -x -s -N public -N topology -e postgis -e uuid-ossp -f datenmanagement/sql/schema.sql [Datenbankname]Warning
Sobald die Datei datenmanagement/sql/schema.sql überschrieben wurde, muss darin die Zeile SELECT pg_catalog.set_config('search_path', '', false); in SELECT pg_catalog.set_config('search_path', 'public', false); geändert werden!
- Python-Prüfungen mittels ruff:
sh linting/ruff- Django-Prüfungen mittels djLint:
sh linting/djlint- CSS-Prüfungen mittels Stylelint:
sh linting/stylelint- JavaScript-Prüfungen mittels ESLint:
sh linting/eslint- alle vorgenannten Prüfungen nacheinander:
sh linting/lint- Tests der App Accounts durchführen:
# ohne uv
python manage.py test accounts
# mit uv
uv run manage.py test accounts- Tests der App Toolbox durchführen:
# ohne uv
python manage.py test toolbox
# mit uv
uv run manage.py test toolbox-
Tests der App Datenmanagement durchführen:
- Einzeltest (Beispiel):
# ohne uv python manage.py test datenmanagement.tests.StrassenTest.test_create # mit uv uv run manage.py test datenmanagement.tests.StrassenTest.test_create
- alle Tests:
# ohne uv python manage.py test datenmanagement # mit uv uv run manage.py test datenmanagement
-
Tests der App Antragsmanagement durchführen:
- Einzeltest (Beispiel):
# ohne uv python manage.py test antragsmanagement.tests.CleanupEventRequestCommentCreateViewTest.test_post_create_success # mit uv uv run manage.py test antragsmanagement.tests.CleanupEventRequestCommentCreateViewTest.test_post_create_success
- alle Tests:
# ohne uv python manage.py test antragsmanagement # mit uv uv run manage.py test antragsmanagement
-
Tests der App BEMAS durchführen:
- Einzeltest (Beispiel):
# ohne uv python manage.py test bemas.tests.OriginatorModelTest.test_delete # mit uv uv run manage.py test bemas.tests.OriginatorModelTest.test_delete
- alle Tests:
# ohne uv python manage.py test bemas # mit uv uv run manage.py test bemas
-
Tests der App FMM durchführen:
- Einzeltest (Beispiel):
# ohne uv python manage.py test fmm.tests.FmfModelTest.test_create # mit uv uv run manage.py test fmm.tests.FmfModelTest.test_create
- alle Tests:
# ohne uv python manage.py test fmm # mit uv uv run manage.py test fmm
-
Tests der App GDI.HRO Codelists durchführen:
- Einzeltest (Beispiel):
# ohne uv python manage.py test gdihrocodelists.tests.CodelistValueModelTest.test_create # mit uv uv run manage.py test gdihrocodelists.tests.CodelistValueModelTest.test_create
- alle Tests:
# ohne uv python manage.py test gdihrocodelists # mit uv uv run manage.py test gdihrocodelists
-
Tests der App GDI.HRO Metadata durchführen:
- Einzeltest (Beispiel):
# ohne uv python manage.py test gdihrometadata.tests.DataTypeModelTest.test_create # mit uv uv run manage.py test gdihrometadata.tests.DataTypeModelTest.test_create
- alle Tests:
# ohne uv python manage.py test gdihrometadata # mit uv uv run manage.py test gdihrometadata
- neuen Branch erstellen – Name des Branches:
- bei Features:
feature/<app-name>/<feature-name>(Beispiel:feature/datenmanagement/edit-model-foobar) - bei Bugfixes:
bugfix/<app-name>/<bugfix-name>(Beispiel:bugfix/accounts/emails)
- bei Features:
- Änderungen linten und testen (siehe oben)
- Änderungen committen und Commit(s) pushen
- Pull-Request im Branch
mainerstellen - Review anfordern und durchführen lassen
- ggf. Änderungen im Nachgang des Reviews committen und Commit(s) pushen
- Pull-Request im Branch
mainabschließen:- Commit-Message gemäß der Syntax der Conventional-Commit gestalten
- mit der Option Squash and merge mergen
Bei Commits und Pull-Requests in der Branch main werden folgende GitHub-Actions ausgeführt:
- Linting: Linting gemäß
.github/workflows/linting.yml - Tests: Tests gemäß
.github/workflows/tests.yml - Release: Release gemäß
.github/workflows/release.yml