From 4b5d1a81390322736667b5cca1d052a2e420ff1b Mon Sep 17 00:00:00 2001 From: Jason Cameron Date: Thu, 7 Dec 2023 18:23:55 -0500 Subject: [PATCH] fix: incorrect method is_empty() (is a property) fix: m2m changed not getting called fix: prevent any admin tomfoolery :( ( note still need to update the reg admin ) --- core/admin.py | 36 +++++++++++++++++++++++++++++++++--- core/models.py | 9 +++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/core/admin.py b/core/admin.py index 500404f..9ad53ee 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,5 +1,5 @@ -from django.contrib import messages from django.contrib.auth.admin import UserAdmin as UserAdmin_ +from django.forms import BaseInlineFormSet from django.urls import reverse from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ @@ -24,12 +24,42 @@ class LogicPuzzleAdmin(admin.ModelAdmin): search_fields = ("hint", "qr_index", "hunt") list_filter = ("hunt",) ordering = ("qr_index",) - - +class TeamMemberInlineFormSet(BaseInlineFormSet): + def __init__(self, *args, **kwargs): + self.request = kwargs.pop('request', None) + super().__init__(*args, **kwargs) + + @property + def deleted_count(self): + # Count the number of forms marked for deletion + return sum(1 for form in self.forms if form.cleaned_data.get('DELETE')) + + @property + def total_count(self): + # Count the number of forms with new items added + return sum(1 for form in self.forms if form.cleaned_data and not form.cleaned_data.get('DELETE')) + + + def clean(self): + super().clean() + total_objs = self.total_count - self.deleted_count + if total_objs > self.instance.hunt.max_team_size: + raise ValidationError(f"Teams for hunt: {self.instance.hunt.name} can only have a max of {self.instance.hunt.max_team_size} members. You tried to set it to {total_objs}") + elif self.instance.is_solo and total_objs > 1: + raise ValidationError("Solo groups can only have one member") + elif total_objs <= 0: + if self.request is not None: + messages.warning(self.request, f"Deleted team {self.instance.name} as there were zero members.") + self.instance.delete() + +class TeamMemberInline(admin.TabularInline): + model = Team.members.through + formset = TeamMemberInlineFormSet class TeamAdmin(admin.ModelAdmin): readonly_fields = ("path",) inlines = [ InviteInLine, + TeamMemberInline ] search_fields = ("name", "members__username") list_filter = ("hunt", "name") diff --git a/core/models.py b/core/models.py index 303783a..610c323 100644 --- a/core/models.py +++ b/core/models.py @@ -387,8 +387,12 @@ class Meta: ] -@receiver(m2m_changed, sender=Team) -def remove_empty_teams(sender, instance: Team, action, **kwargs): +from django.db.models.signals import m2m_changed +from django.dispatch import receiver +from django.core.exceptions import ValidationError + +@receiver(m2m_changed, sender=Team.members.through) +def team_m2m_clean(sender, instance, action, **kwargs): if action == "post_clear": try: instance.delete() @@ -398,3 +402,4 @@ def remove_empty_teams(sender, instance: Team, action, **kwargs): if instance.is_empty(): print("Deleting empty team: ", instance.name) instance.delete() +