Attach Assignment to LearningPath

This commit is contained in:
Daniel Egger 2023-04-05 15:13:41 +02:00
parent 13b580468d
commit b0cc789549
9 changed files with 303 additions and 53 deletions

View File

@ -97,7 +97,6 @@ if [ "$SKIP_SETUP" = false ]; then
echo "python server/manage.py create_default_courses $course_param" echo "python server/manage.py create_default_courses $course_param"
python server/manage.py create_default_courses $course_param python server/manage.py create_default_courses $course_param
python server/manage.py create_default_notifications python server/manage.py create_default_notifications
python server/manage.py create_default_assignments
# make django translations # make django translations
(cd server && python manage.py compilemessages) (cd server && python manage.py compilemessages)

View File

@ -1,23 +1,20 @@
from wagtail.blocks import StreamValue from vbv_lernwelt.assignment.models import TaskContentStreamBlock
from vbv_lernwelt.assignment.models import (
TaskContentStreamBlock,
)
from vbv_lernwelt.assignment.tests.assignment_factories import ( from vbv_lernwelt.assignment.tests.assignment_factories import (
PerformanceObjectiveBlockFactory,
AssignmentListPageFactory,
AssignmentFactory, AssignmentFactory,
TaskBlockFactory, AssignmentListPageFactory,
ExplanationBlockFactory, ExplanationBlockFactory,
PerformanceObjectiveBlockFactory,
TaskBlockFactory,
UserTextInputBlockFactory, UserTextInputBlockFactory,
) )
from vbv_lernwelt.core.utils import replace_whitespace from vbv_lernwelt.core.utils import replace_whitespace
from vbv_lernwelt.course.consts import COURSE_UK from vbv_lernwelt.course.consts import COURSE_UK
from vbv_lernwelt.course.models import CoursePage from vbv_lernwelt.course.models import CoursePage
from wagtail.blocks import StreamValue
def create_assignments(): def create_uk_assignments(course_id=COURSE_UK):
course_page = CoursePage.objects.get(course_id=COURSE_UK) course_page = CoursePage.objects.get(course_id=course_id)
assignment_page = AssignmentListPageFactory( assignment_page = AssignmentListPageFactory(
parent=course_page, parent=course_page,
) )

View File

@ -1,9 +0,0 @@
import djclick as click
from vbv_lernwelt.assignment.creators.create_assignments import create_assignments
@click.command()
def command():
print("Creating default assignments")
create_assignments()

View File

@ -1,10 +1,11 @@
# Generated by Django 3.2.13 on 2023-04-04 11:49 # Generated by Django 3.2.13 on 2023-04-04 11:49
from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import vbv_lernwelt.assignment.models
import wagtail.blocks import wagtail.blocks
import wagtail.fields import wagtail.fields
from django.db import migrations, models
import vbv_lernwelt.assignment.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -12,34 +13,144 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('wagtailcore', '0069_log_entry_jsonfield'), ("wagtailcore", "0069_log_entry_jsonfield"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Assignment', name="Assignment",
fields=[ fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), (
('starting_position', models.TextField(help_text='Erläuterung der Ausgangslage')), "page_ptr",
('effort_required', models.CharField(blank=True, help_text='Zeitaufwand als Text', max_length=100)), models.OneToOneField(
('performance_objectives', wagtail.fields.StreamField([('performance_objective', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())]))], blank=True, help_text='Leistungsziele des Auftrags', use_json_field=True)), auto_created=True,
('assessment_description', models.TextField(blank=True, help_text='Beschreibung der Bewertung')), on_delete=django.db.models.deletion.CASCADE,
('assessment_document_url', models.CharField(blank=True, help_text='URL zum Beeurteilungsinstrument', max_length=255)), parent_link=True,
('tasks', wagtail.fields.StreamField([('task', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock()), ('file_submission_required', wagtail.blocks.BooleanBlock(required=False)), ('content', wagtail.blocks.StreamBlock([('explanation', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())])), ('user_text_input', vbv_lernwelt.assignment.models.UserTextInputBlock()), ('user_confirmation', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())]))], blank=True))]))], blank=True, help_text='Teilaufgaben', use_json_field=True)), primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
(
"starting_position",
models.TextField(help_text="Erläuterung der Ausgangslage"),
),
(
"effort_required",
models.CharField(
blank=True, help_text="Zeitaufwand als Text", max_length=100
),
),
(
"performance_objectives",
wagtail.fields.StreamField(
[
(
"performance_objective",
wagtail.blocks.StructBlock(
[("text", wagtail.blocks.TextBlock())]
),
)
],
blank=True,
help_text="Leistungsziele des Auftrags",
use_json_field=True,
),
),
(
"assessment_description",
models.TextField(
blank=True, help_text="Beschreibung der Bewertung"
),
),
(
"assessment_document_url",
models.CharField(
blank=True,
help_text="URL zum Beeurteilungsinstrument",
max_length=255,
),
),
(
"tasks",
wagtail.fields.StreamField(
[
(
"task",
wagtail.blocks.StructBlock(
[
("title", wagtail.blocks.TextBlock()),
(
"file_submission_required",
wagtail.blocks.BooleanBlock(required=False),
),
(
"content",
wagtail.blocks.StreamBlock(
[
(
"explanation",
wagtail.blocks.StructBlock(
[
(
"text",
wagtail.blocks.TextBlock(),
)
]
),
),
(
"user_text_input",
vbv_lernwelt.assignment.models.UserTextInputBlock(),
),
(
"user_confirmation",
wagtail.blocks.StructBlock(
[
(
"text",
wagtail.blocks.TextBlock(),
)
]
),
),
],
blank=True,
),
),
]
),
)
],
blank=True,
help_text="Teilaufgaben",
use_json_field=True,
),
),
], ],
options={ options={
'verbose_name': 'Auftrag', "verbose_name": "Auftrag",
}, },
bases=('wagtailcore.page',), bases=("wagtailcore.page",),
), ),
migrations.CreateModel( migrations.CreateModel(
name='AssignmentListPage', name="AssignmentListPage",
fields=[ fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), (
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
], ],
options={ options={
'abstract': False, "abstract": False,
}, },
bases=('wagtailcore.page',), bases=("wagtailcore.page",),
), ),
] ]

View File

@ -1,9 +1,27 @@
from django.db import models from django.db import models
from slugify import slugify
from wagtail import blocks from wagtail import blocks
from wagtail.admin.panels import FieldPanel from wagtail.admin.panels import FieldPanel
from wagtail.fields import StreamField from wagtail.fields import StreamField
from wagtail.models import Page from wagtail.models import Page
from vbv_lernwelt.core.model_utils import find_available_slug
from vbv_lernwelt.course.models import CourseBasePage
class AssignmentListPage(CourseBasePage):
subpage_types = ["assignment.Assignment"]
parent_page_types = ["course.CoursePage"]
def save(self, clean=True, user=None, log_action=False, **kwargs):
self.slug = find_available_slug(
slugify(f"{self.get_parent().slug}-assignment", allow_unicode=True)
)
super(AssignmentListPage, self).save(clean, user, log_action, **kwargs)
def __str__(self):
return f"{self.title}"
# class AssignmentSubmission(modModel): # class AssignmentSubmission(modModel):
# created_at = models.DateTimeField(auto_now_add=True) # created_at = models.DateTimeField(auto_now_add=True)
@ -55,7 +73,7 @@ class TaskBlock(blocks.StructBlock):
label = "Teilauftrag" label = "Teilauftrag"
class Assignment(Page): class Assignment(CourseBasePage):
starting_position = models.TextField(help_text="Erläuterung der Ausgangslage") starting_position = models.TextField(help_text="Erläuterung der Ausgangslage")
effort_required = models.CharField( effort_required = models.CharField(
max_length=100, help_text="Zeitaufwand als Text", blank=True max_length=100, help_text="Zeitaufwand als Text", blank=True
@ -101,7 +119,8 @@ class Assignment(Page):
class Meta: class Meta:
verbose_name = "Auftrag" verbose_name = "Auftrag"
def save(self, clean=True, user=None, log_action=False, **kwargs):
class AssignmentListPage(Page): self.slug = find_available_slug(
subpage_types = ["assignment.Assignment"] slugify(f"{self.get_parent().slug}-{self.title}", allow_unicode=True)
parent_page_types = ["course.CoursePage"] )
super(Assignment, self).save(clean, user, log_action, **kwargs)

View File

@ -3,15 +3,13 @@ from factory import SubFactory
from vbv_lernwelt.assignment.models import ( from vbv_lernwelt.assignment.models import (
Assignment, Assignment,
TaskBlock,
AssignmentListPage, AssignmentListPage,
TaskContentStreamBlock,
UserTextInputBlock,
)
from vbv_lernwelt.assignment.models import (
ExplanationBlock, ExplanationBlock,
UserConfirmationBlock,
PerformanceObjectiveBlock, PerformanceObjectiveBlock,
TaskBlock,
TaskContentStreamBlock,
UserConfirmationBlock,
UserTextInputBlock,
) )
from vbv_lernwelt.core.utils import replace_whitespace from vbv_lernwelt.core.utils import replace_whitespace

View File

@ -1,6 +1,7 @@
import djclick as click import djclick as click
from wagtail.models import Page from wagtail.models import Page
from vbv_lernwelt.assignment.creators.create_assignments import create_uk_assignments
from vbv_lernwelt.competence.create_uk_competence_profile import ( from vbv_lernwelt.competence.create_uk_competence_profile import (
create_uk_competence_profile, create_uk_competence_profile,
create_uk_fr_competence_profile, create_uk_fr_competence_profile,
@ -137,6 +138,7 @@ def create_course_uk_de():
create_versicherungsvermittlerin_with_categories( create_versicherungsvermittlerin_with_categories(
course_id=COURSE_UK, title="Überbetriebliche Kurse" course_id=COURSE_UK, title="Überbetriebliche Kurse"
) )
create_uk_assignments(course_id=COURSE_UK)
create_uk_learning_path(course_id=COURSE_UK) create_uk_learning_path(course_id=COURSE_UK)
create_uk_competence_profile(course_id=COURSE_UK) create_uk_competence_profile(course_id=COURSE_UK)
create_default_media_library(course_id=COURSE_UK) create_default_media_library(course_id=COURSE_UK)

View File

@ -5,6 +5,7 @@ from slugify import slugify
from wagtail.models import Locale, Page, Site from wagtail.models import Locale, Page, Site
from wagtail_localize.models import LocaleSynchronization from wagtail_localize.models import LocaleSynchronization
from vbv_lernwelt.assignment.models import Assignment
from vbv_lernwelt.core.admin import User from vbv_lernwelt.core.admin import User
from vbv_lernwelt.course.consts import COURSE_UK, COURSE_UK_FR from vbv_lernwelt.course.consts import COURSE_UK, COURSE_UK_FR
from vbv_lernwelt.course.models import CoursePage from vbv_lernwelt.course.models import CoursePage
@ -18,6 +19,7 @@ from vbv_lernwelt.learnpath.tests.learning_path_factories import (
LearningUnitFactory, LearningUnitFactory,
MediaLibraryBlockFactory, MediaLibraryBlockFactory,
TopicFactory, TopicFactory,
AssignmentBlockFactory,
) )
@ -282,6 +284,20 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst.
title="Reflexion", title="Reflexion",
parent=circle, parent=circle,
) )
LearningContentFactory(
title="Überprüfen einer Motorfahrzeug-Versicherungspolice",
parent=circle,
contents=[
(
"assignment",
AssignmentBlockFactory(
assignment=Assignment.objects.get(
slug__startswith="überbetriebliche-kurse-assignment-überprüfen-einer-motorfahrzeugs"
)
),
)
],
)
LearningContentFactory( LearningContentFactory(
title="Feedback", title="Feedback",
parent=circle, parent=circle,

View File

@ -1,20 +1,137 @@
# Generated by Django 3.2.13 on 2023-04-04 08:28 # Generated by Django 3.2.13 on 2023-04-04 08:28
from django.db import migrations
import wagtail.blocks import wagtail.blocks
import wagtail.fields import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('learnpath', '0001_initial'), ("learnpath", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='learningcontent', model_name="learningcontent",
name='contents', name="contents",
field=wagtail.fields.StreamField([('video', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('resource', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock()), ('text', wagtail.blocks.RichTextBlock(required=False))])), ('exercise', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('learningmodule', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('online_training', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('media_library', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('document', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('test', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('book', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('assignment', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('assignment', wagtail.blocks.PageChooserBlock(help_text='Choose the corresponding assignment.', required=True))])), ('placeholder', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.TextBlock())])), ('feedback', wagtail.blocks.StructBlock([])), ('attendance_day', wagtail.blocks.StructBlock([('description', wagtail.blocks.TextBlock())]))], use_json_field=None), field=wagtail.fields.StreamField(
[
(
"video",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"resource",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
("text", wagtail.blocks.RichTextBlock(required=False)),
]
),
),
(
"exercise",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"learningmodule",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"online_training",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"media_library",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"document",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"test",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"book",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"assignment",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
(
"assignment",
wagtail.blocks.PageChooserBlock(
help_text="Choose the corresponding assignment.",
required=True,
),
),
]
),
),
(
"placeholder",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
("feedback", wagtail.blocks.StructBlock([])),
(
"attendance_day",
wagtail.blocks.StructBlock(
[("description", wagtail.blocks.TextBlock())]
),
),
],
use_json_field=None,
),
), ),
] ]