From 53000ed287eaf1c85f41727f4b02df860aba54a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kr=C3=B6ger?= Date: Fri, 5 Sep 2025 10:35:01 +0200 Subject: [PATCH] Refuse to change multi to single attribute if there are values Prevent users from accidentally changing multi attributes to single ones without changing all the attribute values before to contain only one. --- serveradmin/serverdb/forms.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/serveradmin/serverdb/forms.py b/serveradmin/serverdb/forms.py index e66264b2..b21a9743 100644 --- a/serveradmin/serverdb/forms.py +++ b/serveradmin/serverdb/forms.py @@ -1,7 +1,8 @@ from django import forms from django.core.exceptions import ValidationError +from django.db.models.aggregates import Count -from serveradmin.serverdb.models import ServertypeAttribute, Attribute +from serveradmin.serverdb.models import ServertypeAttribute, Attribute, ServerStringAttribute class ServertypeAdminForm(forms.ModelForm): @@ -41,7 +42,7 @@ class Meta: fields = '__all__' def clean(self): - attr_type = self.cleaned_data.get('type') or self.instance.type # New or existing attribute ? + attr_type = self.cleaned_data.get('type') or self.instance.type # New or existing attribute ? if attr_type != 'relation' and self.cleaned_data.get('target_servertype') is not None: raise ValidationError('Attribute type must be relation when target servertype is selected!') @@ -49,4 +50,12 @@ def clean(self): if attr_type == 'inet' and self.cleaned_data.get('multi') is True: raise ValidationError('Multi attributes of type inet are not supported!') - super().clean() \ No newline at end of file + if self.cleaned_data.get('multi') is False: + any_attrs_have_multiple_values = ServerStringAttribute.get_model(self.instance.type).objects.filter( + attribute_id=self.instance.attribute_id).values('server_id').annotate( + occurences=Count('server_id')).filter(occurences__gt=1).exists() + if any_attrs_have_multiple_values: + raise ValidationError( + 'Refusing to make attribute type single because one ore more objects still have multiple values!') + + super().clean()