diff --git a/mensa_app/__pycache__/admin.cpython-314.pyc b/mensa_app/__pycache__/admin.cpython-314.pyc index 8bd90d7..5d48f81 100644 Binary files a/mensa_app/__pycache__/admin.cpython-314.pyc and b/mensa_app/__pycache__/admin.cpython-314.pyc differ diff --git a/mensa_app/__pycache__/models.cpython-314.pyc b/mensa_app/__pycache__/models.cpython-314.pyc index 7bf82a8..53d1c05 100644 Binary files a/mensa_app/__pycache__/models.cpython-314.pyc and b/mensa_app/__pycache__/models.cpython-314.pyc differ diff --git a/mensa_app/admin.py b/mensa_app/admin.py index 4a2b7fa..8ed593c 100644 --- a/mensa_app/admin.py +++ b/mensa_app/admin.py @@ -3,7 +3,48 @@ from django.contrib import admin # Register your models here. from .models import Person # Ersetze dies durch deine echten Klassennamen -admin.site.register(Person) +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 Join‑Model + verbose_name = 'Kind' + verbose_name_plural = 'Kinder' + extra = 0 # Keine leeren Zeilen anzeigen + + # ---------------------------------------------------------- + # **WICHTIG:** Hier wird der zu verwendende FK explizit genannt + # ---------------------------------------------------------- + fk_name = 'person' # <-- legt fest, welcher FK gemeint ist + + 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) +class PersonAdmin(admin.ModelAdmin): + list_display = ('user', 'rolle', 'klasse') + search_fields = ['user__username', 'klasse'] + ordering = ('rolle',) + + # ---- Inline für Eltern (Rolle Mitarbeit/Chef) ---- + inlines = [PersonInlineChildren] # Zeigt das Kinder‑Inline nur bei passenden Rollen an + + def has_change_permission(self, request, obj=None): + """ + Optional: Verhindere, dass ein Schüler seine eigene Rolle oder die Zuordnung ändert. + """ + return super().has_change_permission(request, obj) from .models import Schulwoche # Ersetze dies durch deine echten Klassennamen diff --git a/mensa_app/models.py b/mensa_app/models.py index 99d39ad..05735a3 100644 --- a/mensa_app/models.py +++ b/mensa_app/models.py @@ -16,14 +16,59 @@ from PIL import Image as PilImage class Person(models.Model): """Repräsentiert Schüler oder Lehrer.""" user = models.OneToOneField(User, on_delete=models.CASCADE) - rolle = models.CharField(max_length=20, choices=[('schueler', 'Schüler'), ('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 + # ---------------------------------------------------------------------- + # Neue Many‑to‑Many 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ück‑Beziehung (nicht benötigt) + help_text=( + "Eltern können hier die ihnen zugewiesenen Schüler hinzufügen. Für Schüler bleibt dieses Feld leer." + ) + ) + + # ------------------------------------------------------------------ + # Optional: Hilfsmethode, die alle Kinder zurückgibt, ggf. mit einer Sortierung + def get_children_sorted(self): + # Das `order_by('name')` ist ein Beispiel – du kannst deine eigene Sortierung verwenden. + return self.children.order_by('name') + class Meta: verbose_name_plural = "Personen" def __str__(self): - return f"{self.user.username} ({self.rolle})" + if self.children.exists(): + # Wir sammeln alle Kinder‑Namen 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})" + + def clean(self): + """ + Überprüfung für die ManyToMany-Beziehung ``children``: + - Nur Personen mit der Rolle 'mitarbeiter' oder 'chef' (Eltern) dürfen Kinder haben. + - 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'): + # Nicht‑Eltern 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.") + class Schulwoche(models.Model):