CoolFace
Apppublic

HamidX/demo.courses

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
validators.py53 linesDownload Raw Back to common
1"""2Reusable same-organization validation helpers.3 4Centralizes the cross-tenant integrity checks that S3 domain models share, so the5"both sides of a relation must belong to the same organization" rule is written6once and enforced in both `Model.clean()` and serializer `validate()`.7 8These raise Django's ValidationError; DRF serializers translate it to a 400.9Organization values are NEVER taken from client input — they are assigned10server-side from the selected membership — so these checks guard related FKs11(teacher, student, classroom, membership) against pointing at another tenant.12"""13 14from django.core.exceptions import ValidationError15 16 17def validate_same_organization(organization, related_obj, field_name: str) -> None:18    """Ensure `related_obj.organization` matches `organization`.19 20    No-op when either side is unset (other validation handles required-ness).21    """22    if organization is None or related_obj is None:23        return24    related_org_id = getattr(related_obj, "organization_id", None)25    expected_id = getattr(organization, "id", organization)26    if related_org_id is not None and related_org_id != expected_id:27        raise ValidationError(28            {field_name: f"{field_name} must belong to the same organization."}29        )30 31 32def validate_teacher_membership(teacher) -> None:33    """Validate a Teacher's optional membership link.34 35    When `membership` is set it must: belong to the teacher's organization, carry36    the TEACHER role, and be active. Imported lazily to avoid app-loading cycles.37    """38    membership = getattr(teacher, "membership", None)39    if membership is None:40        return41 42    from apps.organizations.models import OrganizationRole43 44    errors = {}45    if teacher.organization_id and membership.organization_id != teacher.organization_id:46        errors["membership"] = "membership must belong to the same organization."47    elif membership.role != OrganizationRole.TEACHER:48        errors["membership"] = "membership role must be 'teacher'."49    elif not membership.is_active:50        errors["membership"] = "membership must be active."51    if errors:52        raise ValidationError(errors)53