|
| 1 | +""" |
| 2 | +Signal receivers for openedx_catalog |
| 3 | +""" |
| 4 | +# pylint: disable=unused-argument |
| 5 | + |
| 6 | +import logging |
| 7 | + |
| 8 | +from django.core.exceptions import ValidationError |
| 9 | +from django.db.models.signals import pre_save |
| 10 | +from django.dispatch import receiver |
| 11 | +from organizations.models import Organization |
| 12 | + |
| 13 | +from .models import CourseRun |
| 14 | + |
| 15 | +logger = logging.getLogger(__name__) |
| 16 | + |
| 17 | + |
| 18 | +@receiver(pre_save, sender=Organization) |
| 19 | +def verify_organization_change(sender, instance, **kwargs): |
| 20 | + """ |
| 21 | + Check that changes to Organization objects won't create invalid relationships. |
| 22 | +
|
| 23 | + Nothing stops users from changing Organization.short_name entries in the Django admin, but any changes other than |
| 24 | + capitalization fixes will result in totally invalid data, as CatalogCourse will be related to an Organization that |
| 25 | + no longer matches the "org" part of the related CourseRun's course IDs. |
| 26 | + """ |
| 27 | + if not instance.pk: |
| 28 | + return # It's a brand new Organization; we don't care |
| 29 | + |
| 30 | + prev_org_code = Organization.objects.get(pk=instance.pk).short_name |
| 31 | + new_org_code = instance.short_name |
| 32 | + |
| 33 | + if new_org_code != prev_org_code: |
| 34 | + # Check if this is going to violate any relationship expectations. |
| 35 | + # Note: we could make the database enforce this by making the CatalogCourse.org relationship use "short_name" as |
| 36 | + # its foreign key ID, but that would also make it extremely difficult to ever "fix" an incorrect Organization's |
| 37 | + # short_name (e.g. change capitalization), because doing so would fail with a foreign key constraint error. |
| 38 | + |
| 39 | + run_course_ids = CourseRun.objects.filter(catalog_course__org=instance).values_list("course_id", flat=True) |
| 40 | + for course_id in run_course_ids: |
| 41 | + if course_id.org.lower() != new_org_code.lower(): |
| 42 | + raise ValidationError( |
| 43 | + f'Changing the org short_name to "{new_org_code}" will result in CourseRun "{course_id}" having ' |
| 44 | + "the incorrect organization code. " |
| 45 | + ) |
0 commit comments