🐛(admin) fix organization validators
When updating an Organization in the Django admin, the validator falsly raises a "duplicated" error because it does not exclude the current object from the database lookup.
This commit is contained in:
@@ -22,8 +22,8 @@ class Migration(migrations.Migration):
|
|||||||
('created_at', models.DateTimeField(auto_now_add=True, help_text='date and time at which a record was created', verbose_name='created at')),
|
('created_at', models.DateTimeField(auto_now_add=True, help_text='date and time at which a record was created', verbose_name='created at')),
|
||||||
('updated_at', models.DateTimeField(auto_now=True, help_text='date and time at which a record was last updated', verbose_name='updated at')),
|
('updated_at', models.DateTimeField(auto_now=True, help_text='date and time at which a record was last updated', verbose_name='updated at')),
|
||||||
('name', models.CharField(max_length=100, verbose_name='name')),
|
('name', models.CharField(max_length=100, verbose_name='name')),
|
||||||
('registration_id_list', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, size=None, validators=[core.models.validate_unique_registration_id], verbose_name='registration ID list')),
|
('registration_id_list', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, size=None, verbose_name='registration ID list')),
|
||||||
('domain_list', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=256), blank=True, default=list, size=None, validators=[core.models.validate_unique_domain], verbose_name='domain list')),
|
('domain_list', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=256), blank=True, default=list, size=None, verbose_name='domain list')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'organization',
|
'verbose_name': 'organization',
|
||||||
|
|||||||
@@ -251,24 +251,6 @@ class OrganizationManager(models.Manager):
|
|||||||
raise ValueError("Should never reach this point.")
|
raise ValueError("Should never reach this point.")
|
||||||
|
|
||||||
|
|
||||||
def validate_unique_registration_id(value):
|
|
||||||
"""
|
|
||||||
Validate that the registration ID values in an array field are unique across all instances.
|
|
||||||
"""
|
|
||||||
if Organization.objects.filter(registration_id_list__overlap=value).exists():
|
|
||||||
raise ValidationError(
|
|
||||||
"registration_id_list value must be unique across all instances."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_unique_domain(value):
|
|
||||||
"""
|
|
||||||
Validate that the domain values in an array field are unique across all instances.
|
|
||||||
"""
|
|
||||||
if Organization.objects.filter(domain_list__overlap=value).exists():
|
|
||||||
raise ValidationError("domain_list value must be unique across all instances.")
|
|
||||||
|
|
||||||
|
|
||||||
class Organization(BaseModel):
|
class Organization(BaseModel):
|
||||||
"""
|
"""
|
||||||
Organization model used to regroup Teams.
|
Organization model used to regroup Teams.
|
||||||
@@ -298,16 +280,14 @@ class Organization(BaseModel):
|
|||||||
verbose_name=_("registration ID list"),
|
verbose_name=_("registration ID list"),
|
||||||
default=list,
|
default=list,
|
||||||
blank=True,
|
blank=True,
|
||||||
validators=[
|
# list overlap validation is done in the validate_unique method
|
||||||
validate_unique_registration_id,
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
domain_list = ArrayField(
|
domain_list = ArrayField(
|
||||||
models.CharField(max_length=256),
|
models.CharField(max_length=256),
|
||||||
verbose_name=_("domain list"),
|
verbose_name=_("domain list"),
|
||||||
default=list,
|
default=list,
|
||||||
blank=True,
|
blank=True,
|
||||||
validators=[validate_unique_domain],
|
# list overlap validation is done in the validate_unique method
|
||||||
)
|
)
|
||||||
|
|
||||||
service_providers = models.ManyToManyField(
|
service_providers = models.ManyToManyField(
|
||||||
@@ -340,6 +320,41 @@ class Organization(BaseModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name} (# {self.pk})"
|
return f"{self.name} (# {self.pk})"
|
||||||
|
|
||||||
|
def validate_unique(self, exclude=None):
|
||||||
|
"""
|
||||||
|
Validate Registration/Domain values in an array field are unique
|
||||||
|
across all instances.
|
||||||
|
|
||||||
|
This can't be done in the field validator because we need to
|
||||||
|
exclude the current object if already in database.
|
||||||
|
"""
|
||||||
|
super().validate_unique(exclude=exclude)
|
||||||
|
|
||||||
|
if self.pk:
|
||||||
|
organization_qs = Organization.objects.exclude(pk=self.pk)
|
||||||
|
else:
|
||||||
|
organization_qs = Organization.objects.all()
|
||||||
|
|
||||||
|
# Check a registration ID can only be present in one organization
|
||||||
|
if (
|
||||||
|
self.registration_id_list
|
||||||
|
and organization_qs.filter(
|
||||||
|
registration_id_list__overlap=self.registration_id_list
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
raise ValidationError(
|
||||||
|
"registration_id_list value must be unique across all instances."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check a domain can only be present in one organization
|
||||||
|
if (
|
||||||
|
self.domain_list
|
||||||
|
and organization_qs.filter(domain_list__overlap=self.domain_list).exists()
|
||||||
|
):
|
||||||
|
raise ValidationError(
|
||||||
|
"domain_list value must be unique across all instances."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
|
class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
|
||||||
"""User model to work with OIDC only authentication."""
|
"""User model to work with OIDC only authentication."""
|
||||||
|
|||||||
Reference in New Issue
Block a user