diff --git a/judge/admin/organization.py b/judge/admin/organization.py index e94a2a2ee..1993df776 100644 --- a/judge/admin/organization.py +++ b/judge/admin/organization.py @@ -6,6 +6,7 @@ from reversion.admin import VersionAdmin from judge.models import Organization +from judge.utils.organization import rename_organization_contests from judge.widgets import AdminHeavySelect2MultipleWidget, AdminMartorWidget @@ -63,6 +64,31 @@ def recalculate_points(self, request, queryset): '%d organizations have scores recalculated.', count) % count) + def save_model(self, request, obj, form, change): + if change and 'slug' in form.changed_data: + # Get the old slug before saving + old_org = Organization.objects.get(pk=obj.pk) + old_slug = old_org.slug + new_slug = obj.slug + + # Save the organization first + super().save_model(request, obj, form, change) + + # Rename contests with new prefix + renamed_count = rename_organization_contests(obj, old_slug, new_slug) + + if renamed_count > 0: + self.message_user( + request, + ngettext( + '%d contest has been renamed with the new organization prefix.', + '%d contests have been renamed with the new organization prefix.', + renamed_count, + ) % renamed_count, + ) + else: + super().save_model(request, obj, form, change) + class OrganizationRequestAdmin(admin.ModelAdmin): list_display = ('username', 'organization', 'state', 'time') diff --git a/judge/utils/organization.py b/judge/utils/organization.py index d02b8e7b9..d33da05f7 100644 --- a/judge/utils/organization.py +++ b/judge/utils/organization.py @@ -8,3 +8,34 @@ def add_admin_to_group(form): g = Group.objects.get(name=settings.GROUP_PERMISSION_FOR_ORG_ADMIN) for admin in all_admins: admin.user.groups.add(g) + + +def rename_organization_contests(organization, old_slug, new_slug): + from judge.models import Contest + + # Generate old and new prefixes (alphanumeric characters only) + old_prefix = ''.join(x for x in old_slug.lower() if x.isalnum()) + '_' + new_prefix = ''.join(x for x in new_slug.lower() if x.isalnum()) + '_' + + if old_prefix == new_prefix: + return 0 + + # Find all contests belonging to this organization that start with the old prefix + org_contests = Contest.objects.filter( + organizations=organization, + is_organization_private=True, + key__startswith=old_prefix, + ) + + renamed_count = 0 + for contest in org_contests: + # Replace the old prefix with the new prefix + new_key = new_prefix + contest.key[len(old_prefix):] + + # Check if the new key already exists + if not Contest.objects.filter(key=new_key).exists(): + contest.key = new_key + contest.save() + renamed_count += 1 + + return renamed_count