Skip to content
Snippets Groups Projects
Verified Commit 79517819 authored by magicfelix's avatar magicfelix Committed by Jonathan Weth
Browse files

Add models for calendar-based data model

parent b9a45f25
No related branches found
No related tags found
3 merge requests!352Draft: Resolve "Add dialog with each lesson's students",!350Resolve "Add simple course book list",!339Draft: Resolve "Migrate to new data model"
# Generated by Django 4.2.4 on 2023-08-13 14:53
import aleksis.apps.alsijil.models
import aleksis.core.managers
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("sites", "0002_alter_domain_unique"),
("chronos", "0015_add_managed_by_app_label"),
("core", "0052_site_related_name"),
("cursus", "0001_initial"),
("alsijil", "0018_add_managed_by_app_label"),
]
operations = [
migrations.CreateModel(
name="Documentation",
fields=[
(
"calendarevent_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="core.calendarevent",
),
),
(
"topic",
models.CharField(blank=True, max_length=255, verbose_name="Lesson topic"),
),
("homework", models.CharField(blank=True, max_length=255, verbose_name="Homework")),
(
"group_note",
models.CharField(blank=True, max_length=255, verbose_name="Group note"),
),
(
"course",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="documentations",
to="cursus.course",
),
),
(
"lesson_event",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="documentation",
to="chronos.lessonevent",
),
),
(
"subject",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="+",
to="cursus.subject",
),
),
],
options={
"verbose_name": "Teaching documentation",
"verbose_name_plural": "Teaching documentations",
},
bases=("core.calendarevent",),
),
migrations.CreateModel(
name="Participation",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"managed_by_app_label",
models.CharField(
blank=True,
editable=False,
max_length=255,
verbose_name="App label of app responsible for managing this instance",
),
),
("extended_data", models.JSONField(default=dict, editable=False)),
("remarks", models.CharField(blank=True, max_length=255)),
(
"documentation",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="participations",
to="alsijil.documentation",
),
),
(
"extra_marks",
models.ManyToManyField(
blank=True, to="alsijil.extramark", verbose_name="Extra marks"
),
),
("groups_of_person", models.ManyToManyField(related_name="+", to="core.group")),
(
"person",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="participations",
to="core.person",
),
),
(
"site",
models.ForeignKey(
default=1,
editable=False,
on_delete=django.db.models.deletion.CASCADE,
related_name="+",
to="sites.site",
),
),
],
options={
"verbose_name": "Participation note",
"verbose_name_plural": "Participation notes",
"ordering": ["documentation", "person__last_name", "person__first_name"],
},
bases=(aleksis.apps.alsijil.models.RegisterObjectRelatedMixin, models.Model),
managers=[
("objects", aleksis.core.managers.AlekSISBaseManager()),
],
),
migrations.AddConstraint(
model_name="participation",
constraint=models.UniqueConstraint(
fields=("documentation", "person"), name="unique_participation_per_documentation"
),
),
migrations.AddConstraint(
model_name="documentation",
constraint=models.CheckConstraint(
check=models.Q(
("course__isnull", True), ("lesson_event__isnull", True), _negated=True
),
name="either_course_or_lesson_event",
),
),
]
......@@ -3,6 +3,7 @@ from typing import Optional, Union
from urllib.parse import urlparse
from django.db import models
from django.db.models import QuerySet
from django.db.models.constraints import CheckConstraint
from django.db.models.query_utils import Q
from django.urls import reverse
......@@ -31,10 +32,12 @@ from aleksis.apps.alsijil.managers import (
)
from aleksis.apps.chronos.managers import GroupPropertiesMixin
from aleksis.apps.chronos.mixins import WeekRelatedMixin
from aleksis.apps.chronos.models import Event, ExtraLesson, LessonPeriod, TimePeriod
from aleksis.apps.chronos.models import Event, ExtraLesson, LessonEvent, LessonPeriod, TimePeriod
from aleksis.apps.chronos.util.format import format_m2m
from aleksis.apps.cursus.models import Course, Subject
from aleksis.core.data_checks import field_validation_data_check_factory
from aleksis.core.mixins import ExtensibleModel, GlobalPermissionModel
from aleksis.core.models import SchoolTerm
from aleksis.core.models import CalendarEvent, Group, SchoolTerm
from aleksis.core.util.core_helpers import get_site_preferences
from aleksis.core.util.model_helpers import ICONS
......@@ -439,6 +442,102 @@ class ExtraMark(ExtensibleModel):
verbose_name_plural = _("Extra marks")
class Documentation(CalendarEvent):
"""A documentation on teaching content in a freely choosable time frame.
Non-personal, includes the topic and homework of the lesson.
"""
# FIXME: DataCheck
course = models.ForeignKey(
Course, models.CASCADE, related_name="documentations", blank=True, null=True
)
lesson_event = models.ForeignKey(
LessonEvent, models.CASCADE, related_name="documentation", blank=True, null=True
)
subject = models.ForeignKey(
Subject, models.CASCADE, related_name="+", blank=True, null=True
)
topic = models.CharField(verbose_name=_("Lesson topic"), max_length=255, blank=True)
homework = models.CharField(verbose_name=_("Homework"), max_length=255, blank=True)
group_note = models.CharField(verbose_name=_("Group note"), max_length=255, blank=True)
def get_subject(self) -> str:
if self.subject:
return self.subject
if self.lesson_event:
if self.lesson_event.subject:
return self.lesson_event.subject
if self.lesson_event.course:
return self.lesson_event.course.subject
if self.course:
return self.course.subject
def get_groups(self) -> QuerySet[Group]:
if self.lesson_event:
return self.lesson_event.actual_groups
if self.course:
return self.course.groups.all()
def __str__(self) -> str:
start_datetime = CalendarEvent.value_start_datetime(self, None)
end_datetime = CalendarEvent.value_end_datetime(self, None)
return f"{format_m2m(self.get_groups())} {self.get_subject()} {start_datetime} - {end_datetime}"
class Meta:
verbose_name = _("Teaching documentation")
verbose_name_plural = _("Teaching documentations")
constraints = [
models.CheckConstraint(
check=~Q(course__isnull=True, lesson_event__isnull=True),
name="either_course_or_lesson_event",
),
]
class Participation(RegisterObjectRelatedMixin, ExtensibleModel):
"""A personal note about a single person.
Used in the class register to note participation and remarks about a student
in a documented unit (e.g. a single lesson event or a custom time frame; see Documentation).
"""
# FIXME: DataChecks
person = models.ForeignKey("core.Person", models.CASCADE, related_name="participations")
groups_of_person = models.ManyToManyField("core.Group", related_name="+")
documentation = models.ForeignKey(
Documentation, models.CASCADE, related_name="participations"
)
remarks = models.CharField(max_length=255, blank=True)
extra_marks = models.ManyToManyField("ExtraMark", blank=True, verbose_name=_("Extra marks"))
def __str__(self) -> str:
return f"{self.documentation}, {self.person}"
class Meta:
verbose_name = _("Participation note")
verbose_name_plural = _("Participation notes")
ordering = [
"documentation",
"person__last_name",
"person__first_name",
]
constraints = [
models.UniqueConstraint(
fields=("documentation", "person"),
name="unique_participation_per_documentation",
),
]
class GroupRole(ExtensibleModel):
data_checks = [field_validation_data_check_factory("alsijil", "GroupRole", "icon")]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment