From 40bd15f37829936f5beaa5508f1dc3f252574a24 Mon Sep 17 00:00:00 2001 From: Martin Putzlocher Date: Fri, 26 Jun 2026 09:29:22 +0200 Subject: [PATCH] =?UTF-8?q?Vorbereitung=20f=C3=BCr=20Erfassung=20neuer=20G?= =?UTF-8?q?erichte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mensa_app/forms.py | 33 ++++++++++++ mensa_app/models.py | 1 + .../templates/mensa_app/add_gericht.html | 32 +++++++++++ .../mensa_app/add_gericht_success.html | 29 ++++++++++ mensa_app/urls.py | 17 +++++- mensa_app/views.py | 54 ++++++++++++++----- 6 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 mensa_app/forms.py create mode 100644 mensa_app/templates/mensa_app/add_gericht.html create mode 100644 mensa_app/templates/mensa_app/add_gericht_success.html diff --git a/mensa_app/forms.py b/mensa_app/forms.py new file mode 100644 index 0000000..d9bcac4 --- /dev/null +++ b/mensa_app/forms.py @@ -0,0 +1,33 @@ +# forms.py + +from django import forms +from .models import Gericht +# Importiere alle Modelle, die für das Formular relevant sind +from .models import Kategorie + +class GerichtForm(forms.ModelForm): + """Definiert die Struktur und Validierungsregeln für das Gericht-Modell.""" + + class Meta: + model = Gericht + fields = [ + 'name', + 'kategorie', + 'preis', + 'ist_vegetarisch', + 'ist_allergene_frei', + 'allergene', + 'beschreibung', # Neues Feld für Zutaten/Rohstoffe + 'bilder', # Das Bild-Feld + 'ist_dauerangebot' + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # Wir können hier zusätzliche Validierungen oder Widgets einbinden + # Beispiel: Erzwinge das Betreten der Kategorie-Auswahl + self.fields['kategorie'].required = True + + # Hier könntest du auch einen Fallback für den Preis hinzufügen, falls er nicht gesetzt ist + if 'initial' in kwargs: # Wird bei GET-Requests genutzt + self.initial['preis'] = 0.00 diff --git a/mensa_app/models.py b/mensa_app/models.py index fb88a67..d99ca4b 100644 --- a/mensa_app/models.py +++ b/mensa_app/models.py @@ -128,6 +128,7 @@ class Gericht(models.Model): ) ist_vegetarisch = models.BooleanField(default=False) ist_allergene_frei = models.BooleanField(default=False) + beschreibung = models.TextField(blank=True, null=True) # Zutaten/Rohstoffe Beschreibung (Textfeld für V1) allergene = models.TextField(blank=True, default="") preis = models.DecimalField(max_digits=5, decimal_places=2, default=0.00) diff --git a/mensa_app/templates/mensa_app/add_gericht.html b/mensa_app/templates/mensa_app/add_gericht.html new file mode 100644 index 0000000..f89c48e --- /dev/null +++ b/mensa_app/templates/mensa_app/add_gericht.html @@ -0,0 +1,32 @@ + + + + + + +
+

Neue Speiseart hinzufügen

+ + {# !!! KRITISCH WICHTIG: enctype muss für Dateiuploads stehen !!! #} +
+ {% csrf_token %} + + + {# Man kann die komplexe Struktur durch eine einfache Schleife ersetzen #} + {% for field in form %} +
+ + {{ field }} + + + {% if field.errors %} +

{{ field.errors }}

+ {% endif %} +
+ {% endfor %} + + +
+
+ + diff --git a/mensa_app/templates/mensa_app/add_gericht_success.html b/mensa_app/templates/mensa_app/add_gericht_success.html new file mode 100644 index 0000000..72f716c --- /dev/null +++ b/mensa_app/templates/mensa_app/add_gericht_success.html @@ -0,0 +1,29 @@ + + + + + Erfolg + + + + +
+
+

🎉 Erfolgreich hinzugefügt! 🎉

+

+ Das Gericht {{ objekt_name }} wurde erfolgreich in das Menüsystem übernommen. +

+

+ Du kannst nun die Details überprüfen und weitere Gerichte hinzufügen. +

+
+ + +
+ + diff --git a/mensa_app/urls.py b/mensa_app/urls.py index 0a3ecbe..49ea019 100644 --- a/mensa_app/urls.py +++ b/mensa_app/urls.py @@ -7,5 +7,20 @@ urlpatterns = [ path('speisekarte/', GerichtListView.as_view(), name='speisekarte'), path('speiseplan/', SpeiseplanView.as_view(), name='speiseplan'), path('bestellungen/summary/', BestellSummaryView.as_view(), name='bestell_summary'), - path('userlist/', {},"" ), +] + +# ACHTUNG: Hier benötigen wir jetzt eine separate View für die Erfolgsmeldung! +# Wir nutzen hierfür ein sehr einfaches TemplateView. +from django.views.generic import TemplateView # Muss oben importiert werden +from .models import Gericht + +class ErfolgTemplateView(TemplateView): + """Zeigt einfach nur die Bestätigung an.""" + template_name = 'mensa_app/add_gericht_success.html' + +urlpatterns += [ + # ... (vorherige Pfade bleiben) ... + path('gerichte/neu/', GerichtCreateView.as_view(), name='add_gericht'), + # NEU: Erfolgsmeldung nach erfolgreichem POST/redirect + path('erfolg/', ErfolgTemplateView.as_view(), name='success_message'), ] diff --git a/mensa_app/views.py b/mensa_app/views.py index ba9d79d..f5b1658 100644 --- a/mensa_app/views.py +++ b/mensa_app/views.py @@ -1,18 +1,20 @@ +# views.py +from django.db.models import Count, Sum from django.shortcuts import render +from django.utils import timezone +from datetime import datetime +from django.views.generic import ListView, TemplateView +from django.views.generic.edit import CreateView +from django.shortcuts import redirect # Importiere die Redirect-Funktion +from .forms import GerichtForm # Importiere dein neues Formular +from .models import Gericht, Menue, SpeiseplanTag, Bestellung -# Create your views here. -from django.views.generic import ListView -from .models import Gericht class GerichtListView(ListView): model = Gericht template_name = 'mensa_app/gericht_liste.html' # Der Pfad zum Template context_object_name = 'alle_gerichte' # Der Name, den wir im Template nutzen -from django.views.generic import TemplateView -from django.utils import timezone -from datetime import datetime -from .models import Menue, Gericht, SpeiseplanTag class SpeiseplanView(TemplateView): template_name = 'mensa_app/speiseplan.html' @@ -51,12 +53,6 @@ class SpeiseplanView(TemplateView): return context -from django.views.generic import TemplateView -from django.utils import timezone -from django.db.models import Count, Sum -from datetime import datetime -from .models import Bestellung, SpeiseplanTag, Gericht, Menue - class BestellSummaryView(TemplateView): template_name = 'mensa_app/bestell_summary.html' @@ -100,3 +96,35 @@ class BestellSummaryView(TemplateView): context['total_umsatz'] = Bestellung.objects.filter(menue__tag__datum=target_date).aggregate(Sum('menue__preis'))['menue__preis__sum'] or 0 return context + +class GerichtCreateView(CreateView): + """ + View zur Erstellung eines neuen Gerichts. + Nutzt das benutzerdefinierte GerichtForm für die gesamte Steuerung. + """ + model = Gericht + form_class = GerichtForm # Verwendet unser Custom-Formular + template_name = 'mensa_app/add_gericht.html' + + def get_success_url(self): + # Die Methode wird ausgeführt, nachdem die View erfolgreich ist + objekt = self.object # Gibt uns das gerade gespeicherte Objekt zurück + return reverse('speisekarte') + + def form_valid(self, form): + """ + Übersteuert die Standard-Logik: + 1. Speichert zuerst das Gericht (über super()). + 2. Leitet danach auf ein success/confirmation Pattern um. + """ + super().form_valid() # Das eigentliche Speichern des Objekts + + # Hier ist der Haken an Django: Die View wird beim Erfolg automatisch weitergeleitet. + # Wir verwenden einen kleinen Trick, damit wir den Namen im Kontext haben. + + return redirect('success_nach_gerichterstellung') # Leiten auf eine temporäre URL um + + # Optional: Setzen des initialen Datenzustands (z.B. Datum, falls relevant) + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + return context