Add CourseSession serializer and view

This commit is contained in:
Daniel Egger 2022-11-07 14:54:43 +01:00
parent 05e02449c8
commit 17eaf80d2c
8 changed files with 265 additions and 6 deletions

View File

@ -21,6 +21,7 @@ from vbv_lernwelt.core.views import (
) )
from vbv_lernwelt.course.views import ( from vbv_lernwelt.course.views import (
course_page_api_view, course_page_api_view,
get_course_sessions,
mark_course_completion, mark_course_completion,
request_course_completion, request_course_completion,
) )
@ -59,6 +60,7 @@ urlpatterns = [
name="generate_web_component_icons"), name="generate_web_component_icons"),
# course # course
path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"),
path(r"api/course/page/<slug:slug>/", course_page_api_view, path(r"api/course/page/<slug:slug>/", course_page_api_view,
name="course_page_api_view"), name="course_page_api_view"),
path(r"api/course/completion/mark/", mark_course_completion, path(r"api/course/completion/mark/", mark_course_completion,

View File

@ -3,10 +3,15 @@ import djclick as click
from vbv_lernwelt.competence.create_default_competence_profile import ( from vbv_lernwelt.competence.create_default_competence_profile import (
create_default_competence_profile, create_default_competence_profile,
) )
from vbv_lernwelt.course.consts import (
COURSE_TEST_ID,
COURSE_VERSICHERUNGSVERMITTLERIN_ID,
)
from vbv_lernwelt.course.creators.test_course import create_test_course from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.creators.versicherungsvermittlerin import ( from vbv_lernwelt.course.creators.versicherungsvermittlerin import (
create_versicherungsvermittlerin_with_categories, create_versicherungsvermittlerin_with_categories,
) )
from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.learnpath.create_default_learning_path import ( from vbv_lernwelt.learnpath.create_default_learning_path import (
create_default_learning_path, create_default_learning_path,
) )
@ -24,7 +29,6 @@ def command():
create_versicherungsvermittlerin_with_categories() create_versicherungsvermittlerin_with_categories()
create_default_learning_path() create_default_learning_path()
create_default_competence_profile() create_default_competence_profile()
# media library # media library
@ -34,3 +38,13 @@ def command():
# test course # test course
create_test_course() create_test_course()
# course sessions
CourseSession.objects.create(
course_id=COURSE_TEST_ID,
title="Test Lehrgang Session",
)
CourseSession.objects.create(
course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID,
title="Versicherungsvermittler/in Session",
)

View File

@ -0,0 +1,21 @@
# Generated by Django 3.2.13 on 2022-11-07 13:30
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("course", "0002_auto_20221014_0933"),
]
operations = [
migrations.AlterField(
model_name="coursepage",
name="course",
field=models.OneToOneField(
on_delete=django.db.models.deletion.PROTECT, to="course.course"
),
),
]

View File

@ -18,6 +18,30 @@ class Course(models.Model):
class Meta: class Meta:
verbose_name = _("Lehrgang") verbose_name = _("Lehrgang")
def get_learning_path_url(self):
from vbv_lernwelt.learnpath.models import LearningPath
learning_path_page = (
self.coursepage.get_children().exact_type(LearningPath).first()
)
return learning_path_page.specific.get_frontend_url()
def get_competence_url(self):
from vbv_lernwelt.competence.models import CompetenceProfilePage
competence_page = (
self.coursepage.get_children().exact_type(CompetenceProfilePage).first()
)
return competence_page.specific.get_frontend_url()
def get_media_library_url(self):
from vbv_lernwelt.media_library.models import MediaLibraryPage
media_library_page = (
self.coursepage.get_children().exact_type(MediaLibraryPage).first()
)
return media_library_page.specific.get_frontend_url()
def __str__(self): def __str__(self):
return f"{self.title}" return f"{self.title}"
@ -86,8 +110,12 @@ class CourseBasePage(Page):
class CoursePage(CourseBasePage): class CoursePage(CourseBasePage):
content_panels = Page.content_panels content_panels = Page.content_panels
subpage_types = ["learnpath.LearningPath", "media_library.MediaLibraryPage"] subpage_types = [
course = models.ForeignKey("course.Course", on_delete=models.PROTECT) "learnpath.LearningPath",
"competence.CompetenceProfilePage",
"media_library.MediaLibraryPage",
]
course = models.OneToOneField("course.Course", on_delete=models.PROTECT)
class Meta: class Meta:
verbose_name = _("Lehrgang-Seite") verbose_name = _("Lehrgang-Seite")

View File

@ -1,4 +1,4 @@
from vbv_lernwelt.course.models import CourseSessionUser from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
def has_course_access_by_page_request(request, obj): def has_course_access_by_page_request(request, obj):
@ -21,3 +21,14 @@ def has_course_access(user, course):
# TODO check school class access # TODO check school class access
return False return False
def course_sessions_for_user_qs(user):
if user.is_superuser:
return CourseSession.objects.all()
course_sessions = CourseSession.objects.filter(
course_session_user__user=user
).distinct()
return course_sessions

View File

@ -1,6 +1,11 @@
from rest_framework import serializers from rest_framework import serializers
from vbv_lernwelt.course.models import Course, CourseCategory, CourseCompletion from vbv_lernwelt.course.models import (
Course,
CourseCategory,
CourseCompletion,
CourseSession,
)
class CourseSerializer(serializers.ModelSerializer): class CourseSerializer(serializers.ModelSerializer):
@ -34,3 +39,38 @@ class CourseCompletionSerializer(serializers.ModelSerializer):
"completion_status", "completion_status",
"additional_json_data", "additional_json_data",
] ]
class CourseSessionSerializer(serializers.ModelSerializer):
learning_path_url = serializers.SerializerMethodField()
competence_url = serializers.SerializerMethodField()
media_library_url = serializers.SerializerMethodField()
course = serializers.SerializerMethodField()
def get_course(self, obj):
return CourseSerializer(obj.course).data
def get_learning_path_url(self, obj):
return obj.course.get_learning_path_url()
def get_media_library_url(self, obj):
return obj.course.get_media_library_url()
def get_competence_url(self, obj):
return obj.course.get_competence_url()
class Meta:
model = CourseSession
fields = [
"id",
"created_at",
"updated_at",
"course",
"title",
"start_date",
"end_date",
"additional_json_data",
"learning_path_url",
"competence_url",
"media_library_url",
]

View File

@ -7,9 +7,13 @@ from wagtail.models import Page
from vbv_lernwelt.core.utils import api_page_cache_get_or_set from vbv_lernwelt.core.utils import api_page_cache_get_or_set
from vbv_lernwelt.course.models import CourseCompletion from vbv_lernwelt.course.models import CourseCompletion
from vbv_lernwelt.course.permissions import ( from vbv_lernwelt.course.permissions import (
course_sessions_for_user_qs,
has_course_access_by_page_request, has_course_access_by_page_request,
) )
from vbv_lernwelt.course.serializers import CourseCompletionSerializer from vbv_lernwelt.course.serializers import (
CourseCompletionSerializer,
CourseSessionSerializer,
)
from vbv_lernwelt.learnpath.utils import get_wagtail_type from vbv_lernwelt.learnpath.utils import get_wagtail_type
logger = structlog.get_logger(__name__) logger = structlog.get_logger(__name__)
@ -97,3 +101,17 @@ def mark_course_completion(request):
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
return Response({"error": str(e)}, status=404) return Response({"error": str(e)}, status=404)
@api_view(["GET"])
def get_course_sessions(request):
try:
course_sessions = course_sessions_for_user_qs(request.user)
return Response(
status=200, data=CourseSessionSerializer(course_sessions, many=True).data
)
except PermissionDenied as e:
raise e
except Exception as e:
logger.error(e)
return Response({"error": str(e)}, status=404)

View File

@ -0,0 +1,125 @@
# Generated by Django 3.2.13 on 2022-11-07 13:30
import wagtail.blocks
import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("learnpath", "0007_alter_learningcontent_contents"),
]
operations = [
migrations.AlterField(
model_name="learningcontent",
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()),
("url", wagtail.blocks.TextBlock()),
("text", wagtail.blocks.RichTextBlock(required=False)),
]
),
),
(
"placeholder",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
],
use_json_field=None,
),
),
]