Compare commits

...

4 Commits

Author SHA1 Message Date
mputzlocher 5d060587cb Datenbank wieder verfügbar gemacht für Testdaten 2026-06-12 12:51:27 +02:00
mputzlocher eac2457a06 README.md aktualisiert 2026-06-12 10:41:57 +00:00
mputzlocher 6ee0f9ea9d README.md aktualisiert 2026-06-12 10:38:58 +00:00
mputzlocher 0868caf35f nötige Anpassungen nach Merge 2026-06-12 11:15:53 +02:00
8 changed files with 120 additions and 81 deletions
-1
View File
@@ -1,4 +1,3 @@
__pycache__/ __pycache__/
*.pyc *.pyc
*.sqlite3
+26 -4
View File
@@ -6,12 +6,15 @@ Muster-Implementation durch die Lehrkraft in python3 mit Django
## To get started ## To get started
## Vorbereitung der virtuellen Entwicklungsumgebung
in einem Projekt-Vezeichnis über dem eigentlichen SGTMensa-Projekt-Ordner
```bash ```bash
cd SGTMensa
python3 -m venv .venv python3 -m venv .venv
source .venv/bin/activate source .venv/bin/activate
pip install django pip install django
django-admin startproject mensa-core . pip install pillow
``` ```
Falls eine fish-Shell vorliegt: Falls eine fish-Shell vorliegt:
@@ -19,9 +22,27 @@ Falls eine fish-Shell vorliegt:
python3 -m venv .venv python3 -m venv .venv
source .venv/bin/activate.fish source .venv/bin/activate.fish
pip install django pip install django
django-admin startproject mensa-core . pip install pillow
``` ```
## Klonen des eigentlichen Projekts
```bash
git clone https://git.sgtlernen.de/mputzlocher/SGTMensa.git
```
## Starten des Servers
```bash
cd SGTMensa
python manage.py runserver
```
---
# Erweiterte Erklärung einzelner Schritte
### Schritt 1: Die Arbeitsumgebung isolieren (Virtual Environment) ### Schritt 1: Die Arbeitsumgebung isolieren (Virtual Environment)
Bevor du auch nur eine Zeile Code schreibst, erstelle eine eigene Umgebung. Das verhindert, dass sich verschiedene Projekte auf deinem Rechner gegenseitig stören. Bevor du auch nur eine Zeile Code schreibst, erstelle eine eigene Umgebung. Das verhindert, dass sich verschiedene Projekte auf deinem Rechner gegenseitig stören.
@@ -42,9 +63,10 @@ Installiere nur das Nötigste. Für den Start reicht Django.
```bash ```bash
pip install django pip install django
pip install pillow
``` ```
### Schritt 3: Das Projekt initialisieren ### Schritt 3: Das Projekt initialisieren (nur einmalig, beim ersten Start des Projekts)
Erstelle die Struktur eines Django-Projekts. Erstelle die Struktur eines Django-Projekts.
BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

+30 -28
View File
@@ -3,33 +3,35 @@ from django.contrib import admin
# Register your models here. # Register your models here.
from .models import Person # Ersetze dies durch deine echten Klassennamen from .models import Person # Ersetze dies durch deine echten Klassennamen
class PersonInlineChildren(admin.TabularInline):
"""
Inline für das Feld ``children`` (Schüler eines Elternteils).
Nur bei Eltern (Rolle Mitarbeit/Chef) sichtbar.
"""
model = Person.children.through # Das durchschnittliche JoinModel
verbose_name = 'Kind'
verbose_name_plural = 'Kinder'
extra = 0 # Keine leeren Zeilen anzeigen
# ---------------------------------------------------------- # DELTE: Die Option, Kinder zuzuordnen soll zunächst nicht umgesetzt werden.
# **WICHTIG:** Hier wird der zu verwendende FK explizit genannt # class PersonInlineChildren(admin.TabularInline):
# ---------------------------------------------------------- # """
fk_name = 'person' # <-- legt fest, welcher FK gemeint ist # Inline für das Feld ``children`` (Schüler eines Elternteils).
# Nur bei Eltern (Rolle Mitarbeit/Chef) sichtbar.
def has_add_permission(self, request, obj=None): # """
# Erlaube Hinzufügen nur für Eltern (Rolle Eltern) # model = Person.children.through # Das durchschnittliche JoinModel
return obj and obj.rolle in ('eltern') # verbose_name = 'Kind'
# verbose_name_plural = 'Kinder'
def formfield_for_foreignkey(self, db_field, request, **kwargs): # extra = 0 # Keine leeren Zeilen anzeigen
""" #
Verhindere, dass ein Benutzer sich selbst als Kind hinzufügt. # # ----------------------------------------------------------
""" # # **WICHTIG:** Hier wird der zu verwendende FK explizit genannt
if db_field.name == "person": # # ----------------------------------------------------------
# Hier handelt es sich um den FK auf die Person (das Ziel) # fk_name = 'person' # <-- legt fest, welcher FK gemeint ist
kwargs["queryset"] = Person.objects.exclude(pk=self.instance.pk) #
return super().formfield_for_foreignkey(db_field, request, **kwargs) # def has_add_permission(self, request, obj=None):
# # Erlaube Hinzufügen nur für Eltern (Rolle Eltern)
# return obj and obj.rolle in ('eltern')
#
# def formfield_for_foreignkey(self, db_field, request, **kwargs):
# """
# Verhindere, dass ein Benutzer sich selbst als Kind hinzufügt.
# """
# if db_field.name == "person":
# # Hier handelt es sich um den FK auf die Person (das Ziel)
# kwargs["queryset"] = Person.objects.exclude(pk=self.instance.pk)
# return super().formfield_for_foreignkey(db_field, request, **kwargs)
@admin.register(Person) @admin.register(Person)
class PersonAdmin(admin.ModelAdmin): class PersonAdmin(admin.ModelAdmin):
@@ -37,8 +39,8 @@ class PersonAdmin(admin.ModelAdmin):
search_fields = ['user__username', 'klasse'] search_fields = ['user__username', 'klasse']
ordering = ('rolle',) ordering = ('rolle',)
# ---- Inline für Eltern (Rolle Mitarbeit/Chef) ---- # # ---- Inline für Eltern (Rolle Mitarbeit/Chef) ----
inlines = [PersonInlineChildren] # Zeigt das KinderInline nur bei passenden Rollen an # inlines = [PersonInlineChildren] # Zeigt das KinderInline nur bei passenden Rollen an
def has_change_permission(self, request, obj=None): def has_change_permission(self, request, obj=None):
""" """
@@ -0,0 +1,14 @@
# Generated by Django 5.2.14 on 2026-06-12 09:13
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mensa_app', '0005_alter_bestellung_id_alter_gericht_id_and_more'),
('mensa_app', '0009_alter_gericht_time_creation_and_more'),
]
operations = [
]
+50 -48
View File
@@ -19,55 +19,57 @@ class Person(models.Model):
rolle = models.CharField(max_length=20, choices=[('schueler', 'Schüler'), ('eltern', 'Eltern'), ('lehrer', 'Lehrer'), ('mitarbeiter','Mensa-Mitarbeiter'), ('chef','Mensa-Leitung')]) rolle = models.CharField(max_length=20, choices=[('schueler', 'Schüler'), ('eltern', 'Eltern'), ('lehrer', 'Lehrer'), ('mitarbeiter','Mensa-Mitarbeiter'), ('chef','Mensa-Leitung')])
klasse = models.CharField(max_length=4, blank=True, null=True) # Nur für Schüler relevant klasse = models.CharField(max_length=4, blank=True, null=True) # Nur für Schüler relevant
# ----------------------------------------------------------------------
# Neue ManytoMany Beziehung: „Elternteil ↔ Schüler“
# ----------------------------------------------------------------------
children = models.ManyToManyField(
'self',
blank=True,
related_name='parents', # → für einen Schüler: person.parents.all()
symmetrical=False, # Verhindert eine zirkuläre RückBeziehung (nicht benötigt)
help_text=(
"Eltern können hier die ihnen zugewiesenen Schüler hinzufügen. Für Schüler bleibt dieses Feld leer."
)
)
# ------------------------------------------------------------------ # DELETE: Die Eltern-Kinder Beziehung soll zunächst nicht umgesetzt werden.
# Optional: Hilfsmethode, die alle Kinder zurückgibt, ggf. mit einer Sortierung # # ----------------------------------------------------------------------
def get_children_sorted(self): # # Neue ManytoMany Beziehung: „Elternteil ↔ Schüler“
# Das `order_by('name')` ist ein Beispiel du kannst deine eigene Sortierung verwenden. # # ----------------------------------------------------------------------
return self.children.order_by('name') # children = models.ManyToManyField(
# 'self',
class Meta: # blank=True,
verbose_name_plural = "Personen" # related_name='parents', # → für einen Schüler: person.parents.all()
# symmetrical=False, # Verhindert eine zirkuläre RückBeziehung (nicht benötigt)
def __str__(self): # help_text=(
if self.children.exists(): # "Eltern können hier die ihnen zugewiesenen Schüler hinzufügen. Für Schüler bleibt dieses Feld leer."
# Wir sammeln alle KinderNamen in einem String, z.B. mit Komma getrennt. # )
children_names = ', '.join([c.name for c in self.children.all()]) # )
return f"{self.user.username} ({children_names}) ({self.rolle})" #
else: # # ------------------------------------------------------------------
return f"{self.user.username} ({self.rolle})" # # Optional: Hilfsmethode, die alle Kinder zurückgibt, ggf. mit einer Sortierung
# def get_children_sorted(self):
def clean(self): # # Das `order_by('name')` ist ein Beispiel du kannst deine eigene Sortierung verwenden.
""" # return self.children.order_by('name')
Überprüfung für die ManyToMany-Beziehung ``children``: #
- Nur Personen mit der Rolle 'mitarbeiter' oder 'chef' (Eltern) dürfen Kinder haben. # class Meta:
- Ein Schüler darf sich selbst nicht als Kind hinzufügen. # verbose_name_plural = "Personen"
""" #
super().clean() # ruft die Validierungen der Elternklasse auf (hier User/Model) # def __str__(self):
# if self.children.exists():
if self.rolle in ('mitarbeiter', 'chef', 'lehrer'): # # Wir sammeln alle KinderNamen in einem String, z.B. mit Komma getrennt.
# NichtEltern dürfen keine Kinder besitzen # children_names = ', '.join([c.name for c in self.children.all()])
if self.children.exists(): # return f"{self.user.username} ({children_names}) ({self.rolle})"
raise ValidationError( # else:
"Nur Benutzer mit der Rolle 'Eltern' " # return f"{self.user.username} ({self.rolle})"
"dürfen Schüler zuordnen (children)." #
) # def clean(self):
else: # """
# Eltern: Verhindere, dass sie sich selbst als Kind eintragen # Überprüfung für die ManyToMany-Beziehung ``children``:
if self in self.children.all(): # - Nur Personen mit der Rolle 'mitarbeiter' oder 'chef' (Eltern) dürfen Kinder haben.
raise ValidationError("Ein Benutzer darf nicht gleichzeitig Elternteil und eigener Kind sein.") # - Ein Schüler darf sich selbst nicht als Kind hinzufügen.
# """
# super().clean() # ruft die Validierungen der Elternklasse auf (hier User/Model)
#
# if self.rolle in ('mitarbeiter', 'chef', 'lehrer'):
# # NichtEltern dürfen keine Kinder besitzen
# if self.children.exists():
# raise ValidationError(
# "Nur Benutzer mit der Rolle 'Eltern' "
# "dürfen Schüler zuordnen (children)."
# )
# else:
# # Eltern: Verhindere, dass sie sich selbst als Kind eintragen
# if self in self.children.all():
# raise ValidationError("Ein Benutzer darf nicht gleichzeitig Elternteil und eigener Kind sein.")