dhtmlxGantt mit Python

Diese Anleitung erklärt, wie man ein Gantt-Diagramm mit Python unter Verwendung des Django 4 Frameworks und einer RESTful API für den Server einrichtet.

Falls Sie an anderen serverseitigen Integrationen interessiert sind, gibt es Tutorials für verschiedene Plattformen:

Der vollständige Quellcode für dieses Tutorial ist auf GitHub verfügbar.

Voraussetzungen

Stellen Sie sicher, dass Django auf Ihrem System installiert ist. Falls nicht, können Sie diesen Anleitungen folgen:

Schritt 1. Projekt einrichten

Beginnen Sie mit der Erstellung eines neuen Django-Projekts. Führen Sie in Ihrem Projektordner folgenden Befehl aus:

django-admin startproject gantt_rest_python

Sie können entweder die Inhalte des Ordners gantt_rest_python in Ihren aktuellen Ordner verschieben oder in den Ordner wechseln:

cd gantt_rest_python

Um zu überprüfen, ob die Einrichtung funktioniert, starten Sie den Server:

python manage.py runserver

Besuchen Sie http://localhost:8000 in Ihrem Browser. Sie sollten die Standard-Django-Willkommensseite sehen:

start_page

Schritt 2. Hinzufügen von Gantt zur Seite

Erstellen Sie als Nächstes eine neue Django-App für die Gantt-Komponente:

python manage.py startapp gantt

Installieren Sie die erforderlichen REST-Framework-Pakete:

pip install djangorestframework
pip install djangorestframework-jsonapi

Erstellen Sie im Ordner gantt die Verzeichnisse static und templates. Kopieren Sie den Inhalt des codebase-Ordners aus dem Gantt-Paket in das static-Verzeichnis und benennen Sie es zur Klarheit in gantt um.

Erstellen Sie nun eine Datei namens index.html im Verzeichnis templates/gantt und fügen Sie den folgenden Code hinzu:

gantt/templates/gantt/index.html

<html>
    <head>
        {% load static %}
        <script src="{% static "gantt/dhtmlxgantt.js" %}" type="text/javascript">
        </script>
        <link rel="stylesheet" href="{% static "gantt/dhtmlxgantt.css" %}" />
    </head>
    <body>
        <div id="gantt_here" style='width:100%; height:500px;'>
        </div>
        <script>
        gantt.config.date_format = "%Y-%m-%d %H:%i";
 
        gantt.config.open_tree_initially = true;
        gantt.init("gantt_here");
        </script>
    </body>
</html>

Ihre Ordnerstruktur sollte nun folgendermaßen aussehen:

folder_structure

Fügen Sie im views.py-File im gantt-Ordner den folgenden Code hinzu:

gantt/views.py

from django.shortcuts import render
 
def index(request):
    return render(request, 'gantt/index.html')

Richten Sie als Nächstes das Routing ein. Erstellen Sie eine Datei namens urls.py im gantt-Ordner und fügen Sie diesen Code hinzu:

gantt/urls.py

from django.urls import include, re_path
from . import views
from rest_framework.urlpatterns import format_suffix_patterns
 
urlpatterns = [
    re_path(r'^$', views.index, name='index'),
]
urlpatterns = format_suffix_patterns(urlpatterns)

Aktualisieren Sie dann die urls.py-Datei im gantt_rest_python Projektordner, um die neue App einzuschließen:

gantt_rest_python/urls.py

from django.urls import include, re_path
from django.contrib import admin
 
urlpatterns = [
    re_path(r'', include('gantt.urls')),
]

Konfigurieren Sie Pfade für die templates und static Verzeichnisse in der settings.py-Datei im gantt_rest_python Ordner. Fügen Sie diese Zeile oben hinzu:

gantt_rest_python/settings.py

import os

Suchen Sie das TEMPLATES Array und ersetzen Sie 'DIRS': [] durch:

'DIRS': [os.path.join(BASE_DIR, 'gantt/templates')],

Fügen Sie die folgende Zeile am Ende der Datei hinzu:

STATICFILES_DIRS = [os.path.join(BASE_DIR, "gantt/static")]

Starten Sie nun den Server:

python manage.py runserver

Wenn alles korrekt eingerichtet ist, sollten Sie eine Seite mit einem leeren Gantt-Diagramm sehen:

init_gantt

Schritt 3. Laden von Daten

Um Daten zu laden, aktualisieren Sie die settings.py-Datei. Fügen Sie 'rest_framework' und 'gantt.apps.GanttConfig' zum INSTALLED_APPS Array hinzu und inkludieren Sie die REST_FRAMEWORK Konfiguration:

gantt_rest_python/settings.py

INSTALLED_APPS = [
    'gantt.apps.GanttConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]
 
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
    'PAGE_SIZE': 10
}

Deaktivieren Sie den USE_TZ Parameter, um sich mit DHTMLX Gantt, das absolute Daten verwendet, abzustimmen:

USE_TZ = False

Definieren Sie die Task- und Link-Modelle in gantt/models.py:

gantt/models.py

from django.db import models
 
class Task(models.Model):
    id = models.AutoField(primary_key=True, editable=False)
    text = models.CharField(blank=True, max_length=100)
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()
    duration = models.IntegerField()
    progress = models.FloatField()
    parent = models.CharField(max_length=100)
 
class Link(models.Model):
    id = models.AutoField(primary_key=True, editable=False)
    source = models.CharField(max_length=100)
    target = models.CharField(max_length=100)
    type = models.CharField(max_length=100)
    lag = models.IntegerField(blank=True, default=0)

Erstellen Sie Migrationen und wenden Sie sie an:

python manage.py makemigrations gantt
python manage.py migrate

Um einige Beispieldaten hinzuzufügen, öffnen Sie die Python-Shell:

python manage.py shell

Verwenden Sie diese Befehle, um Aufgaben und Links hinzuzufügen:

from gantt.models import Task, Link
 
Aufgaben hinzufügen
===================
t1 = Task(id="10", text="Project #1", start_date="2025-04-01 00:00", end_date="2025-04-03 00:00", duration=2, progress=0.5, parent="0")
t1.save()
Wiederholen Sie für andere Aufgaben...
===================
 
Links hinzufügen
===================
l1 = Link(id="1", source="1", target="2", type="0", lag=0)
l1.save()
Wiederholen Sie für andere Links...
===================

Um dies zu bestätigen, führen Sie aus:

Task.objects.all()
Link.objects.all()

Sie sollten die hinzugefügten Aufgaben und Links sehen.

Erstellen Sie als Nächstes eine Datei namens serializers.py im gantt Ordner, um die Serialisierung zu handhaben:

gantt/serializers.py

from .models import Task, Link
from rest_framework import serializers
 
class TaskSerializer(serializers.ModelSerializer):
    start_date = serializers.DateTimeField(format='%Y-%m-%d %H:%M')
    end_date = serializers.DateTimeField(format='%Y-%m-%d %H:%M')
 
    class Meta:
        model = Task
        fields = ('id','text','start_date','end_date','duration','progress','parent')
 
class LinkSerializer(serializers.ModelSerializer):
    class Meta:
        model = Link
        fields = ('id', 'source', 'target', 'type', 'lag')

Aktualisieren Sie die views.py-Datei, um eine Methode zum Zurückgeben von Daten einzuschließen:

gantt/views.py

from django.shortcuts import render
from .models import Task, Link
from gantt.serializers import TaskSerializer, LinkSerializer
from rest_framework.decorators import api_view
from rest_framework.response import Response
 
def index(request):
    return render(request, 'gantt/index.html')
 
@api_view(['GET'])
def data_list(request, offset):
    tasks = Task.objects.all()
    links = Link.objects.all()
    taskData = TaskSerializer(tasks, many=True)
    linkData = LinkSerializer(links, many=True)
    return Response({
        "tasks": taskData.data,
        "links": linkData.data
    })

Fügen Sie die neue Route zu gantt/urls.py hinzu:

gantt/urls.py

from django.urls import include, re_path
from . import views
 
urlpatterns = [
    re_path(r'^$', views.index, name='index'),
    re_path(r'^data/(.*)$', views.data_list),
]

Aktualisieren Sie schließlich index.html, um Daten zu laden:

gantt/templates/gantt/index.html

gantt.load("/data/", "json");

Starten Sie den Server neu, und Sie sollten nun ein Gantt-Diagramm sehen, das mit Aufgaben und Links gefüllt ist.

gantt

Schritt 4. Änderungen speichern

Um das Speichern von Änderungen zu ermöglichen, fügen Sie Methoden zum Handhaben von POST, PUT und DELETE Anfragen in views.py hinzu. Der vollständige Code-Schnipsel ist oben bereitgestellt.

Aktualisieren Sie die Routen in gantt/urls.py, um Pfade für diese Aktionen einzuschließen.

Aktivieren Sie schließlich den Data Processor in index.html, um diese Aktualisierungen zu verarbeiten:

gantt/templates/gantt/index.html

var dp = new gantt.dataProcessor("/data/");
dp.init(gantt);
dp.setTransactionMode("REST");

Mit dieser Einrichtung können Sie Aufgaben und Links hinzufügen, aktualisieren und löschen. Änderungen bleiben nach einem Neuladen der Seite bestehen.

saving_changes

Speichern der Reihenfolge der Aufgaben

Um die vertikale Reihenfolge der Aufgaben zu verwalten, können Sie den Schritten im Originalleitfaden folgen. Dies beinhaltet das Hinzufügen einer sort_order Eigenschaft, das Aktivieren der Neuanordnung und das Speichern der Reihenfolge in der Datenbank.

Anwendungssicherheit

Während Gantt das Frontend handhabt, liegt die Sicherheit des Backends (z.B. Verhinderung von SQL-Injection, XSS und CSRF-Angriffen) in der Verantwortung des Entwicklers. Weitere Details finden Sie in diesem Artikel.

Fehlerbehebung

Wenn Aufgaben und Links nicht auf der Seite angezeigt werden, lesen Sie den Fehlerbehebungsleitfaden: Fehlerbehebung bei Backend-Integrationsproblemen.

Was kommt als Nächstes

Ihr Gantt-Diagramm ist einsatzbereit. Der vollständige Code ist auf GitHub verfügbar. Schauen Sie sich zusätzliche Leitfäden und Tutorials für andere Backend-Frameworks an.

Zurück nach oben