Add CourseSession serializer and view
This commit is contained in:
parent
05e02449c8
commit
17eaf80d2c
|
|
@ -21,6 +21,7 @@ from vbv_lernwelt.core.views import (
|
|||
)
|
||||
from vbv_lernwelt.course.views import (
|
||||
course_page_api_view,
|
||||
get_course_sessions,
|
||||
mark_course_completion,
|
||||
request_course_completion,
|
||||
)
|
||||
|
|
@ -59,6 +60,7 @@ urlpatterns = [
|
|||
name="generate_web_component_icons"),
|
||||
|
||||
# course
|
||||
path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"),
|
||||
path(r"api/course/page/<slug:slug>/", course_page_api_view,
|
||||
name="course_page_api_view"),
|
||||
path(r"api/course/completion/mark/", mark_course_completion,
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ import djclick as click
|
|||
from vbv_lernwelt.competence.create_default_competence_profile import (
|
||||
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.versicherungsvermittlerin import (
|
||||
create_versicherungsvermittlerin_with_categories,
|
||||
)
|
||||
from vbv_lernwelt.course.models import CourseSession
|
||||
from vbv_lernwelt.learnpath.create_default_learning_path import (
|
||||
create_default_learning_path,
|
||||
)
|
||||
|
|
@ -24,7 +29,6 @@ def command():
|
|||
create_versicherungsvermittlerin_with_categories()
|
||||
|
||||
create_default_learning_path()
|
||||
|
||||
create_default_competence_profile()
|
||||
|
||||
# media library
|
||||
|
|
@ -34,3 +38,13 @@ def command():
|
|||
|
||||
# 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",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -18,6 +18,30 @@ class Course(models.Model):
|
|||
class Meta:
|
||||
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):
|
||||
return f"{self.title}"
|
||||
|
||||
|
|
@ -86,8 +110,12 @@ class CourseBasePage(Page):
|
|||
|
||||
class CoursePage(CourseBasePage):
|
||||
content_panels = Page.content_panels
|
||||
subpage_types = ["learnpath.LearningPath", "media_library.MediaLibraryPage"]
|
||||
course = models.ForeignKey("course.Course", on_delete=models.PROTECT)
|
||||
subpage_types = [
|
||||
"learnpath.LearningPath",
|
||||
"competence.CompetenceProfilePage",
|
||||
"media_library.MediaLibraryPage",
|
||||
]
|
||||
course = models.OneToOneField("course.Course", on_delete=models.PROTECT)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Lehrgang-Seite")
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
@ -21,3 +21,14 @@ def has_course_access(user, course):
|
|||
|
||||
# TODO check school class access
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
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):
|
||||
|
|
@ -34,3 +39,38 @@ class CourseCompletionSerializer(serializers.ModelSerializer):
|
|||
"completion_status",
|
||||
"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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -7,9 +7,13 @@ from wagtail.models import Page
|
|||
from vbv_lernwelt.core.utils import api_page_cache_get_or_set
|
||||
from vbv_lernwelt.course.models import CourseCompletion
|
||||
from vbv_lernwelt.course.permissions import (
|
||||
course_sessions_for_user_qs,
|
||||
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
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
|
@ -97,3 +101,17 @@ def mark_course_completion(request):
|
|||
except Exception as e:
|
||||
logger.error(e)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
]
|
||||
Loading…
Reference in New Issue