Skip to content

Fix CourseMembership.clean() crash on unsaved course & enforce teacher requirement#284

Merged
smattymatty merged 1 commit intomainfrom
260-backend-fix-coursemembershipclean-crash-on-unsaved-course-enforce-teacher-requirement
Feb 13, 2026
Merged

Fix CourseMembership.clean() crash on unsaved course & enforce teacher requirement#284
smattymatty merged 1 commit intomainfrom
260-backend-fix-coursemembershipclean-crash-on-unsaved-course-enforce-teacher-requirement

Conversation

@smattymatty
Copy link
Collaborator

Fix CourseMembership.clean() crash on unsaved course & enforce teacher requirement

Description

Fixes two related issues with course creation and membership validation in the Django admin.

Closes #260

Mandatory Checklist

  • I have read and followed the CONTRIBUTING.md
  • I have linked the related issue above
  • My branch is up to date with main
  • I have tested my changes locally
  • I have added or updated tests where applicable
  • I have not introduced any new linting errors
  • My commit messages are clear and descriptive
  • I have updated documentation if my changes affect public APIs, setup steps, or user-facing behavior

What Changed

1. Guard CourseMembership.clean() against unsaved instances (courses/models.py)

The duplicate-membership check ran CourseMembership.objects.filter(user=self.user, course=self.course) unconditionally. When creating a course with an inline membership in the admin, self.course has no PK yet, causing Django to raise ValueError: Model instances passed to related filters must be saved.

Fixed by wrapping the query in if self.user_id and self.course_id: — skips the DB query when either FK is unsaved. The UniqueConstraint on ["user", "course"] still prevents duplicates at the DB level.

2. Enforce teacher requirement in admin (courses/admin.py)

Added CourseAdmin.save_related() override that checks after all inlines are saved that the course has at least one CourseMembership with role="teacher" and status="enrolled". Raises ValidationError if not, preventing:

  • Creating courses with no teacher
  • Removing the last teacher via admin

The API flow (auto-creating teacher membership on course creation) is unchanged.

3. Tests

  • courses/tests/test_CourseMembership.py — 3 new tests: unsaved course doesn't crash, unsaved user doesn't crash, duplicates still caught when both are saved
  • courses/tests/test_admin.py — new file, 5 tests: no teacher blocked, with teacher succeeds, only students blocked, invited teacher doesn't count, removing last teacher blocked

How to Test

cd backend/EduLite
python manage.py test courses

All 1020 backend tests pass (157 in courses app, 8 new).

To manually verify:

  1. Open Django admin → Courses → Add Course
  2. Try saving without adding a membership inline → should show validation error
  3. Add a teacher membership inline → should save successfully
  4. Edit the course, delete the teacher membership → should show validation error

@vercel
Copy link

vercel bot commented Feb 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
edulite Ready Ready Preview, Comment Feb 13, 2026 3:55pm

@github-actions
Copy link

PR Template Check

All checks passed.

@smattymatty smattymatty merged commit 6f7317b into main Feb 13, 2026
7 checks passed
@smattymatty smattymatty deleted the 260-backend-fix-coursemembershipclean-crash-on-unsaved-course-enforce-teacher-requirement branch February 13, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BACKEND] Fix CourseMembership.clean() crash on unsaved course & enforce teacher requirement

1 participant