feat: praxis assignments
This commit is contained in:
parent
80cc83cde0
commit
5d4e6983de
|
|
@ -289,6 +289,9 @@ class CourseSessionUser(models.Model):
|
||||||
]
|
]
|
||||||
ordering = ["user__last_name", "user__first_name", "user__email"]
|
ordering = ["user__last_name", "user__first_name", "user__email"]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.user} ({self.course_session.title})"
|
||||||
|
|
||||||
|
|
||||||
class CircleDocument(models.Model):
|
class CircleDocument(models.Model):
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||||
|
|
||||||
@admin.register(LearningMentor)
|
@admin.register(LearningMentor)
|
||||||
class LearningMentorAdmin(admin.ModelAdmin):
|
class LearningMentorAdmin(admin.ModelAdmin):
|
||||||
list_display = [
|
def student_count(self, obj):
|
||||||
"mentor_email",
|
return obj.students.count()
|
||||||
]
|
|
||||||
|
student_count.short_description = "Students"
|
||||||
|
|
||||||
|
list_display = ["mentor", "course", "student_count"]
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,6 @@ from django.apps import AppConfig
|
||||||
class LearningMentorConfig(AppConfig):
|
class LearningMentorConfig(AppConfig):
|
||||||
default_auto_field = "django.db.models.BigAutoField"
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = "vbv_lernwelt.learning_mentor"
|
name = "vbv_lernwelt.learning_mentor"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
import vbv_lernwelt.learning_mentor.signals # noqa F401
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 3.2.20 on 2023-12-06 09:32
|
# Generated by Django 3.2.20 on 2023-12-07 07:52
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
@ -9,8 +9,8 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("course", "0005_course_enable_circle_documents"),
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
("course", "0005_course_enable_circle_documents"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
@ -18,26 +18,38 @@ class Migration(migrations.Migration):
|
||||||
name="LearningMentor",
|
name="LearningMentor",
|
||||||
fields=[
|
fields=[
|
||||||
(
|
(
|
||||||
"mentor_email",
|
"id",
|
||||||
models.EmailField(
|
models.BigAutoField(
|
||||||
max_length=254, primary_key=True, serialize=False
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"course",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE, to="course.course"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"mentor",
|
"mentor",
|
||||||
models.OneToOneField(
|
models.OneToOneField(
|
||||||
blank=True,
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
null=True,
|
|
||||||
on_delete=django.db.models.deletion.SET_NULL,
|
|
||||||
to=settings.AUTH_USER_MODEL,
|
to=settings.AUTH_USER_MODEL,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"students",
|
"students",
|
||||||
models.ManyToManyField(
|
models.ManyToManyField(
|
||||||
related_name="students", to="course.CourseSessionUser"
|
blank=True,
|
||||||
|
related_name="students",
|
||||||
|
to="course.CourseSessionUser",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
options={
|
||||||
|
"unique_together": {("mentor", "course")},
|
||||||
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,20 @@ from vbv_lernwelt.course.models import CourseSessionUser
|
||||||
|
|
||||||
|
|
||||||
class LearningMentor(models.Model):
|
class LearningMentor(models.Model):
|
||||||
mentor_email = models.EmailField(primary_key=True)
|
mentor = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
mentor = models.OneToOneField(
|
course = models.ForeignKey("course.Course", on_delete=models.CASCADE)
|
||||||
User, on_delete=models.SET_NULL, null=True, blank=True
|
|
||||||
|
students = models.ManyToManyField(
|
||||||
|
CourseSessionUser,
|
||||||
|
related_name="students",
|
||||||
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
students = models.ManyToManyField(CourseSessionUser, related_name="students")
|
class Meta:
|
||||||
|
unique_together = [["mentor", "course"]]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.mentor_email
|
return f"{self.mentor} ({self.course.title})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def course_sessions(self):
|
def course_sessions(self):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db.models.signals import m2m_changed
|
||||||
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
from .models import LearningMentor
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(m2m_changed, sender=LearningMentor.students.through)
|
||||||
|
def validate_student(sender, instance, action, reverse, model, pk_set, **kwargs):
|
||||||
|
if action == "pre_add":
|
||||||
|
students = model.objects.filter(pk__in=pk_set)
|
||||||
|
for student in students:
|
||||||
|
if student.course_session.course != instance.course:
|
||||||
|
raise ValidationError(
|
||||||
|
"Student (CourseSessionUser) does not match the course for this mentor."
|
||||||
|
)
|
||||||
|
|
@ -33,7 +33,7 @@ class AttendanceServicesTestCase(TestCase):
|
||||||
self.circle, _ = create_circle(title="Circle", course_page=self.course_page)
|
self.circle, _ = create_circle(title="Circle", course_page=self.course_page)
|
||||||
|
|
||||||
self.assignment = create_assignment(
|
self.assignment = create_assignment(
|
||||||
course=self.course, assignment_type=AssignmentType.CASEWORK
|
course=self.course, assignment_type=AssignmentType.PRAXIS_ASSIGNMENT
|
||||||
)
|
)
|
||||||
|
|
||||||
AssignmentCompletion.objects.create(
|
AssignmentCompletion.objects.create(
|
||||||
|
|
@ -92,5 +92,5 @@ class AttendanceServicesTestCase(TestCase):
|
||||||
# THEN
|
# THEN
|
||||||
assignment = result[0]
|
assignment = result[0]
|
||||||
self.assertEqual(assignment.pending_evaluations, 1)
|
self.assertEqual(assignment.pending_evaluations, 1)
|
||||||
self.assertEqual(assignment.title, "Dummy Assignment (CASEWORK)")
|
self.assertEqual(assignment.title, "Dummy Assignment (PRAXIS_ASSIGNMENT)")
|
||||||
self.assertEqual(assignment.circle_id, self.circle.id)
|
self.assertEqual(assignment.circle_id, self.circle.id)
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,7 @@ def get_praxis_assignments(
|
||||||
for course_session_assignment in CourseSessionAssignment.objects.filter(
|
for course_session_assignment in CourseSessionAssignment.objects.filter(
|
||||||
course_session=course_session,
|
course_session=course_session,
|
||||||
learning_content__content_assignment__assignment_type__in=[
|
learning_content__content_assignment__assignment_type__in=[
|
||||||
# TODO: Switch to PRAXIS_ASSIGNMENT
|
AssignmentType.PRAXIS_ASSIGNMENT.value,
|
||||||
AssignmentType.CASEWORK.value,
|
|
||||||
],
|
],
|
||||||
):
|
):
|
||||||
learning_content = course_session_assignment.learning_content
|
learning_content = course_session_assignment.learning_content
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue