From f0a6abdb1c3bb2f7829d07818ffd99379ccb6244 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de>
Date: Sat, 1 May 2021 01:49:20 +0200
Subject: [PATCH] Restrict choices (foreign keys & m2m) in admin forms to other
 objects of the event of the edited instance

Additionally, improve how requirements are shown for AK admin (multiple checkboxes instead of multiselect widget)
---
 AKModel/admin.py | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/AKModel/admin.py b/AKModel/admin.py
index d03fc5f1..c9828f10 100644
--- a/AKModel/admin.py
+++ b/AKModel/admin.py
@@ -151,6 +151,24 @@ class WishFilter(SimpleListFilter):
         return queryset
 
 
+class AKAdminForm(forms.ModelForm):
+    class Meta:
+        widgets = {
+            'requirements': forms.CheckboxSelectMultiple,
+        }
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        # Filter possible values for foreign keys & m2m when event is specified
+        if hasattr(self.instance, "event") and self.instance.event is not None:
+            self.fields["category"].queryset = AKCategory.objects.filter(event=self.instance.event)
+            self.fields["track"].queryset = AKTrack.objects.filter(event=self.instance.event)
+            self.fields["owners"].queryset = AKOwner.objects.filter(event=self.instance.event)
+            self.fields["requirements"].queryset = AKRequirement.objects.filter(event=self.instance.event)
+            self.fields["conflicts"].queryset = AK.objects.filter(event=self.instance.event)
+            self.fields["prerequisites"].queryset = AK.objects.filter(event=self.instance.event)
+
+
 @admin.register(AK)
 class AKAdmin(SimpleHistoryAdmin):
     model = AK
@@ -159,6 +177,7 @@ class AKAdmin(SimpleHistoryAdmin):
     list_editable = ['short_name', 'track', 'interest']
     ordering = ['pk']
     actions = ['wiki_export']
+    form = AKAdminForm
 
     def is_wish(self, obj):
         return obj.wish
@@ -195,6 +214,10 @@ class RoomForm(AvailabilitiesFormMixin, forms.ModelForm):
         kwargs['initial'] = dict()
         super().__init__(*args, **kwargs)
         self.initial = {**self.initial, **kwargs['initial']}
+        # Filter possible values for m2m when event is specified
+        if hasattr(self.instance, "event") and self.instance.event is not None:
+            self.fields["properties"].queryset = AKRequirement.objects.filter(event=self.instance.event)
+
 
 
 @admin.register(Room)
@@ -219,14 +242,23 @@ class RoomAdmin(admin.ModelAdmin):
         )
 
 
+class AKSlotAdminForm(forms.ModelForm):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        # Filter possible values for foreign keys when event is specified
+        if hasattr(self.instance, "event") and self.instance.event is not None:
+            self.fields["ak"].queryset = AK.objects.filter(event=self.instance.event)
+            self.fields["room"].queryset = Room.objects.filter(event=self.instance.event)
+
+
 @admin.register(AKSlot)
 class AKSlotAdmin(admin.ModelAdmin):
     model = AKSlot
     list_display = ['id', 'ak', 'room', 'start', 'duration', 'event']
     list_filter = ['room', 'event']
     ordering = ['start']
-
     readonly_fields = ['ak_details_link', 'updated']
+    form = AKSlotAdminForm
 
     def get_urls(self):
         urls = super().get_urls()
@@ -283,8 +315,22 @@ class AKOrgaMessageAdmin(admin.ModelAdmin):
     readonly_fields = ['timestamp', 'ak', 'text']
 
 
+class ConstraintViolationAdminForm(forms.ModelForm):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        # Filter possible values for foreign keys & m2m when event is specified
+        if hasattr(self.instance, "event") and self.instance.event is not None:
+            self.fields["ak_owner"].queryset = AKOwner.objects.filter(event=self.instance.event)
+            self.fields["room"].queryset = Room.objects.filter(event=self.instance.event)
+            self.fields["requirement"].queryset = AKRequirement.objects.filter(event=self.instance.event)
+            self.fields["category"].queryset = AKCategory.objects.filter(event=self.instance.event)
+            self.fields["aks"].queryset = AK.objects.filter(event=self.instance.event)
+            self.fields["ak_slots"].queryset = AKSlot.objects.filter(event=self.instance.event)
+
+
 @admin.register(ConstraintViolation)
 class ConstraintViolationAdmin(admin.ModelAdmin):
     list_display = ['type', 'level', 'get_details']
     list_filter = ['event']
     readonly_fields = ['timestamp']
+    form = ConstraintViolationAdminForm
-- 
GitLab