VBV-519: Anpassungen Darstellung Wissens- und Verständnisfragen für Lernende
This commit is contained in:
parent
589453a8dc
commit
f8c6daf9eb
|
|
@ -3,23 +3,25 @@ import dayjs from "dayjs";
|
||||||
import LocalizedFormat from "dayjs/plugin/localizedFormat";
|
import LocalizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export const formatDueDate = (start: string, end: string) => {
|
export const formatDueDate = (start: string, end?: string) => {
|
||||||
dayjs.extend(LocalizedFormat);
|
dayjs.extend(LocalizedFormat);
|
||||||
const startDayjs = dayjs(start);
|
const startDayjs = dayjs(start);
|
||||||
const endDayjs = dayjs(end);
|
|
||||||
const startDateString = getDateString(startDayjs);
|
const startDateString = getDateString(startDayjs);
|
||||||
const endDateString = getDateString(endDayjs);
|
|
||||||
|
|
||||||
// if startDayjs isundefined, dont show the day twice
|
let endDayjs;
|
||||||
|
let endDateString;
|
||||||
|
if (end) {
|
||||||
|
endDayjs = dayjs(end);
|
||||||
|
endDateString = getDateString(endDayjs);
|
||||||
|
}
|
||||||
|
|
||||||
if (!startDayjs.isValid() && !endDayjs.isValid()) {
|
// at least `start` must be provided and valid
|
||||||
|
if (!startDayjs.isValid()) {
|
||||||
return i18next.t("Termin nicht festgelegt");
|
return i18next.t("Termin nicht festgelegt");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!startDayjs || (!startDayjs.isValid() && endDayjs.isValid())) {
|
// when only `start` is provided, show only the start date with time
|
||||||
return `${endDateString} ${getTimeString(endDayjs)} ${endDayjs.format("[Uhr]")}`;
|
if (!endDayjs || !endDayjs.isValid()) {
|
||||||
}
|
|
||||||
if (!endDayjs || (!endDayjs.isValid() && startDayjs.isValid())) {
|
|
||||||
return `${startDateString} ${getTimeString(startDayjs)} ${startDayjs.format(
|
return `${startDateString} ${getTimeString(startDayjs)} ${startDayjs.format(
|
||||||
"[Uhr]"
|
"[Uhr]"
|
||||||
)}`;
|
)}`;
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,20 @@
|
||||||
import { useTranslation } from "i18next-vue";
|
import { useTranslation } from "i18next-vue";
|
||||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||||
import LearningContentSimpleLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentSimpleLayout.vue";
|
import LearningContentSimpleLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentSimpleLayout.vue";
|
||||||
import type {
|
import type { AssignmentCompletion, LearningContentEdoniqTest } from "@/types";
|
||||||
Assignment,
|
|
||||||
AssignmentCompletion,
|
|
||||||
LearningContentEdoniqTest,
|
|
||||||
} from "@/types";
|
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
import { itPost } from "@/fetchHelpers";
|
import { itPost } from "@/fetchHelpers";
|
||||||
import { useQuery } from "@urql/vue";
|
import { useQuery } from "@urql/vue";
|
||||||
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
||||||
import { useCurrentCourseSession } from "@/composables";
|
import { useCurrentCourseSession } from "@/composables";
|
||||||
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import {
|
||||||
|
formatDueDate,
|
||||||
|
getDateString,
|
||||||
|
} from "../../../../components/dueDates/dueDatesUtils";
|
||||||
|
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
@ -21,6 +24,11 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
|
const courseSessionsStore = useCourseSessionsStore();
|
||||||
|
|
||||||
|
const courseSessionEdoniqTest = computed(() => {
|
||||||
|
return courseSessionsStore.findCourseSessionEdoniqTest(props.content.id);
|
||||||
|
});
|
||||||
|
|
||||||
const queryResult = useQuery({
|
const queryResult = useQuery({
|
||||||
query: ASSIGNMENT_COMPLETION_QUERY,
|
query: ASSIGNMENT_COMPLETION_QUERY,
|
||||||
|
|
@ -31,21 +39,25 @@ const queryResult = useQuery({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const assignment = computed(
|
|
||||||
() => queryResult.data.value?.assignment as Assignment | undefined
|
|
||||||
);
|
|
||||||
const assignmentCompletion = computed(
|
const assignmentCompletion = computed(
|
||||||
() =>
|
() =>
|
||||||
queryResult.data.value?.assignment_completion as AssignmentCompletion | undefined
|
queryResult.data.value?.assignment_completion as AssignmentCompletion | undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
const completionStatus = computed(() => {
|
const completionStatus = computed(() => {
|
||||||
return assignmentCompletion.value?.completion_status ?? "IN_PROGRESS";
|
return assignmentCompletion.value?.completion_status ?? "";
|
||||||
});
|
});
|
||||||
|
|
||||||
const termsAccepted = ref(false);
|
const termsAccepted = ref(false);
|
||||||
const extendedTimeTest = ref(false);
|
const extendedTimeTest = ref(false);
|
||||||
|
|
||||||
|
const deadlineInPast = computed(() => {
|
||||||
|
// with 16 minutes buffer
|
||||||
|
return dayjs(courseSessionEdoniqTest.value?.deadline_start)
|
||||||
|
.add(16, "minute")
|
||||||
|
.isBefore(dayjs());
|
||||||
|
});
|
||||||
|
|
||||||
async function startTest() {
|
async function startTest() {
|
||||||
log.info("start test", props.content);
|
log.info("start test", props.content);
|
||||||
const response = await itPost("/api/core/edoniq-test/redirect/", {
|
const response = await itPost("/api/core/edoniq-test/redirect/", {
|
||||||
|
|
@ -62,24 +74,46 @@ async function startTest() {
|
||||||
:title="props.content.title"
|
:title="props.content.title"
|
||||||
:learning-content="props.content"
|
:learning-content="props.content"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<div class="container-medium">
|
||||||
<div v-if="queryResult.data" class="container-medium">
|
<section class="py-4">
|
||||||
<div v-if="completionStatus !== 'IN_PROGRESS'">
|
<h3>{{ $t("a.Aufgabe") }}</h3>
|
||||||
<div v-if="completionStatus === 'EVALUATION_SUBMITTED'">
|
<p class="mt-2 text-lg">{{ $t("edoniqTest.testDescription") }}</p>
|
||||||
{{ $t("a.Bewertung") }}:
|
</section>
|
||||||
{{ assignmentCompletion?.evaluation_points }}
|
|
||||||
{{ $t("assignment.von x Punkten", { x: assignment?.max_points }) }}
|
|
||||||
</div>
|
|
||||||
<div v-else>Ergebnisse abgeben, Bewertung ausstehend</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<p
|
|
||||||
v-if="props.content.description"
|
|
||||||
class="default-wagtail-rich-text text-large my-4"
|
|
||||||
v-html="props.content.description"
|
|
||||||
></p>
|
|
||||||
|
|
||||||
<div class="my-8">
|
<section v-if="courseSessionEdoniqTest" class="py-4">
|
||||||
|
<h3>{{ $t("a.Abgabetermin") }}</h3>
|
||||||
|
<p class="mt-2 text-lg">
|
||||||
|
{{
|
||||||
|
$t("edoniqTest.submitDateDescription", {
|
||||||
|
x: formatDueDate(courseSessionEdoniqTest.deadline_start),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="py-4">
|
||||||
|
<h3>{{ $t("a.Kompetenznachweis") }}</h3>
|
||||||
|
<div class="mt-2 text-lg">
|
||||||
|
{{
|
||||||
|
$t("circlePage.Dieser Inhalt gehört zu x", {
|
||||||
|
x: content.competence_certificate?.title,
|
||||||
|
})
|
||||||
|
}}.
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 text-lg">
|
||||||
|
<router-link
|
||||||
|
:to="content.competence_certificate?.frontend_url ?? ''"
|
||||||
|
class="link"
|
||||||
|
data-cy="show-results"
|
||||||
|
>
|
||||||
|
{{ $t("circlePage.Im KompetenzNavi anschauen") }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section v-if="!completionStatus">
|
||||||
|
<div class="mt-8 border p-8">
|
||||||
|
<h3 class="mb-4">{{ $t("edoniqTest.checkboxTitle") }}</h3>
|
||||||
<ItCheckbox
|
<ItCheckbox
|
||||||
v-if="props.content.checkbox_text"
|
v-if="props.content.checkbox_text"
|
||||||
:checkbox-item="{
|
:checkbox-item="{
|
||||||
|
|
@ -90,7 +124,7 @@ async function startTest() {
|
||||||
@toggle="termsAccepted = !termsAccepted"
|
@toggle="termsAccepted = !termsAccepted"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-8 border-t pt-8">
|
<div class="my-8 border-b border-t py-8">
|
||||||
<h3 class="mb-4">{{ $t("edoniqTest.qualifiesForExtendedTimeTitle") }}</h3>
|
<h3 class="mb-4">{{ $t("edoniqTest.qualifiesForExtendedTimeTitle") }}</h3>
|
||||||
<ItCheckbox
|
<ItCheckbox
|
||||||
v-if="props.content.has_extended_time_test"
|
v-if="props.content.has_extended_time_test"
|
||||||
|
|
@ -103,17 +137,53 @@ async function startTest() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="my-8">
|
<div>
|
||||||
<button
|
<button
|
||||||
:disabled="!termsAccepted"
|
:disabled="!termsAccepted || deadlineInPast"
|
||||||
class="btn-primary inline-flex items-center"
|
class="btn-primary inline-flex items-center"
|
||||||
@click="startTest()"
|
@click="startTest()"
|
||||||
>
|
>
|
||||||
{{ $t("edoniqTest.startTest") }}
|
{{ $t("edoniqTest.startTest") }}
|
||||||
<it-icon-external-link class="it-icon ml-2 h-5 w-5"></it-icon-external-link>
|
<it-icon-external-link class="it-icon ml-2 h-5 w-5"></it-icon-external-link>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<div v-if="deadlineInPast" class="text-red-700">
|
||||||
|
{{ $t("edoniqTest.deadlineInPast") }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ $t("a.Abgabetermin") }}:
|
||||||
|
{{ getDateString(dayjs(courseSessionEdoniqTest?.deadline_start)) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
|
<section v-else>
|
||||||
|
<div v-if="assignmentCompletion" class="mt-8 border p-8">
|
||||||
|
<ItSuccessAlert :text="$t('edoniqTest.testSubmitted')" />
|
||||||
|
<div class="my-4">
|
||||||
|
{{ $t("a.Resultat") }}:
|
||||||
|
<span class="font-bold">
|
||||||
|
{{ assignmentCompletion.evaluation_points }}
|
||||||
|
</span>
|
||||||
|
{{
|
||||||
|
$t("assignment.von x Punkten", {
|
||||||
|
x: assignmentCompletion.evaluation_max_points,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<button class="btn-primary inline-flex items-center" @click="startTest()">
|
||||||
|
{{ $t("edoniqTest.viewResults") }}
|
||||||
|
<it-icon-external-link
|
||||||
|
class="it-icon ml-2 h-5 w-5"
|
||||||
|
></it-icon-external-link>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</LearningContentSimpleLayout>
|
</LearningContentSimpleLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -121,3 +121,10 @@ export function userAssignmentPoints(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pointsToGrade(points: number, maxPoints: number) {
|
||||||
|
// round to half-grades
|
||||||
|
const grade = Math.round((points / maxPoints) * 10);
|
||||||
|
const halfGrade = grade / 2;
|
||||||
|
return Math.min(halfGrade, 5) + 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import type {
|
||||||
CourseSession,
|
CourseSession,
|
||||||
CourseSessionAssignment,
|
CourseSessionAssignment,
|
||||||
CourseSessionAttendanceCourse,
|
CourseSessionAttendanceCourse,
|
||||||
|
CourseSessionEdoniqTest,
|
||||||
CourseSessionUser,
|
CourseSessionUser,
|
||||||
DueDate,
|
DueDate,
|
||||||
ExpertSessionUser,
|
ExpertSessionUser,
|
||||||
|
|
@ -264,6 +265,16 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findCourseSessionEdoniqTest(
|
||||||
|
contentId?: number
|
||||||
|
): CourseSessionEdoniqTest | undefined {
|
||||||
|
if (contentId && currentCourseSession.value) {
|
||||||
|
return currentCourseSession.value.edoniq_tests.find(
|
||||||
|
(a) => a.learning_content_id === contentId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
uniqueCourseSessionsByCourse,
|
uniqueCourseSessionsByCourse,
|
||||||
allCurrentCourseSessions,
|
allCurrentCourseSessions,
|
||||||
|
|
@ -280,6 +291,7 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
removeDocument,
|
removeDocument,
|
||||||
findAttendanceCourse,
|
findAttendanceCourse,
|
||||||
findCourseSessionAssignment,
|
findCourseSessionAssignment,
|
||||||
|
findCourseSessionEdoniqTest,
|
||||||
allDueDates,
|
allDueDates,
|
||||||
|
|
||||||
// use `useCurrentCourseSession` whenever possible
|
// use `useCurrentCourseSession` whenever possible
|
||||||
|
|
|
||||||
|
|
@ -485,6 +485,14 @@ export interface CourseSessionAssignment {
|
||||||
evaluation_deadline_start: string;
|
evaluation_deadline_start: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CourseSessionEdoniqTest {
|
||||||
|
id: number;
|
||||||
|
course_session_id: number;
|
||||||
|
learning_content_id: number;
|
||||||
|
deadline_id: number;
|
||||||
|
deadline_start: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CourseSession {
|
export interface CourseSession {
|
||||||
id: number;
|
id: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
|
|
@ -500,6 +508,7 @@ export interface CourseSession {
|
||||||
media_library_url: string;
|
media_library_url: string;
|
||||||
attendance_courses: CourseSessionAttendanceCourse[];
|
attendance_courses: CourseSessionAttendanceCourse[];
|
||||||
assignments: CourseSessionAssignment[];
|
assignments: CourseSessionAssignment[];
|
||||||
|
edoniq_tests: CourseSessionEdoniqTest[];
|
||||||
documents: CircleDocument[];
|
documents: CircleDocument[];
|
||||||
users: CourseSessionUser[];
|
users: CourseSessionUser[];
|
||||||
due_dates: DueDate[];
|
due_dates: DueDate[];
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,14 @@ from vbv_lernwelt.course.utils import get_wagtail_default_site
|
||||||
from vbv_lernwelt.course_session.models import (
|
from vbv_lernwelt.course_session.models import (
|
||||||
CourseSessionAssignment,
|
CourseSessionAssignment,
|
||||||
CourseSessionAttendanceCourse,
|
CourseSessionAttendanceCourse,
|
||||||
|
CourseSessionEdoniqTest,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.feedback.services import update_feedback_response
|
from vbv_lernwelt.feedback.services import update_feedback_response
|
||||||
from vbv_lernwelt.learnpath.models import (
|
from vbv_lernwelt.learnpath.models import (
|
||||||
Circle,
|
Circle,
|
||||||
LearningContentAssignment,
|
LearningContentAssignment,
|
||||||
LearningContentAttendanceCourse,
|
LearningContentAttendanceCourse,
|
||||||
|
LearningContentEdoniqTest,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.learnpath.tests.learning_path_factories import (
|
from vbv_lernwelt.learnpath.tests.learning_path_factories import (
|
||||||
CircleFactory,
|
CircleFactory,
|
||||||
|
|
@ -168,6 +170,19 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
|
||||||
)
|
)
|
||||||
csa.submission_deadline.save()
|
csa.submission_deadline.save()
|
||||||
|
|
||||||
|
cset = CourseSessionEdoniqTest.objects.create(
|
||||||
|
course_session=cs_bern,
|
||||||
|
learning_content=LearningContentEdoniqTest.objects.get(
|
||||||
|
slug="test-lehrgang-lp-circle-fahrzeug-lc-wissens-und-verständnisfragen"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
cset.deadline.start = timezone.make_aware(
|
||||||
|
(next_monday + relativedelta(days=3)).replace(
|
||||||
|
hour=21, minute=0, second=0, microsecond=0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
cset.deadline.save()
|
||||||
|
|
||||||
cs_zurich = CourseSession.objects.create(
|
cs_zurich = CourseSession.objects.create(
|
||||||
course_id=COURSE_TEST_ID,
|
course_id=COURSE_TEST_ID,
|
||||||
title="Test Zürich 2022 a",
|
title="Test Zürich 2022 a",
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,12 @@ from vbv_lernwelt.course.models import (
|
||||||
from vbv_lernwelt.course_session.models import (
|
from vbv_lernwelt.course_session.models import (
|
||||||
CourseSessionAssignment,
|
CourseSessionAssignment,
|
||||||
CourseSessionAttendanceCourse,
|
CourseSessionAttendanceCourse,
|
||||||
|
CourseSessionEdoniqTest,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.course_session.serializers import (
|
from vbv_lernwelt.course_session.serializers import (
|
||||||
CourseSessionAssignmentSerializer,
|
CourseSessionAssignmentSerializer,
|
||||||
CourseSessionAttendanceCourseSerializer,
|
CourseSessionAttendanceCourseSerializer,
|
||||||
|
CourseSessionEdoniqTestSerializer,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.duedate.models import DueDate
|
from vbv_lernwelt.duedate.models import DueDate
|
||||||
from vbv_lernwelt.duedate.serializers import DueDateSerializer
|
from vbv_lernwelt.duedate.serializers import DueDateSerializer
|
||||||
|
|
@ -61,6 +63,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
documents = serializers.SerializerMethodField()
|
documents = serializers.SerializerMethodField()
|
||||||
attendance_courses = serializers.SerializerMethodField()
|
attendance_courses = serializers.SerializerMethodField()
|
||||||
assignments = serializers.SerializerMethodField()
|
assignments = serializers.SerializerMethodField()
|
||||||
|
edoniq_tests = serializers.SerializerMethodField()
|
||||||
due_dates = serializers.SerializerMethodField()
|
due_dates = serializers.SerializerMethodField()
|
||||||
|
|
||||||
def get_course(self, obj):
|
def get_course(self, obj):
|
||||||
|
|
@ -97,6 +100,11 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
CourseSessionAssignment.objects.filter(course_session=obj), many=True
|
CourseSessionAssignment.objects.filter(course_session=obj), many=True
|
||||||
).data
|
).data
|
||||||
|
|
||||||
|
def get_edoniq_tests(self, obj):
|
||||||
|
return CourseSessionEdoniqTestSerializer(
|
||||||
|
CourseSessionEdoniqTest.objects.filter(course_session=obj), many=True
|
||||||
|
).data
|
||||||
|
|
||||||
def get_due_dates(self, obj):
|
def get_due_dates(self, obj):
|
||||||
due_dates = DueDate.objects.filter(course_session=obj)
|
due_dates = DueDate.objects.filter(course_session=obj)
|
||||||
return DueDateSerializer(due_dates, many=True).data
|
return DueDateSerializer(due_dates, many=True).data
|
||||||
|
|
@ -114,6 +122,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
"additional_json_data",
|
"additional_json_data",
|
||||||
"attendance_courses",
|
"attendance_courses",
|
||||||
"assignments",
|
"assignments",
|
||||||
|
"edoniq_tests",
|
||||||
"learning_path_url",
|
"learning_path_url",
|
||||||
"cockpit_url",
|
"cockpit_url",
|
||||||
"competence_url",
|
"competence_url",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from rest_framework import serializers
|
||||||
from vbv_lernwelt.course_session.models import (
|
from vbv_lernwelt.course_session.models import (
|
||||||
CourseSessionAssignment,
|
CourseSessionAssignment,
|
||||||
CourseSessionAttendanceCourse,
|
CourseSessionAttendanceCourse,
|
||||||
|
CourseSessionEdoniqTest,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -61,3 +62,21 @@ class CourseSessionAssignmentSerializer(serializers.ModelSerializer):
|
||||||
def get_submission_deadline_start(self, obj):
|
def get_submission_deadline_start(self, obj):
|
||||||
if obj.submission_deadline:
|
if obj.submission_deadline:
|
||||||
return obj.submission_deadline.start
|
return obj.submission_deadline.start
|
||||||
|
|
||||||
|
|
||||||
|
class CourseSessionEdoniqTestSerializer(serializers.ModelSerializer):
|
||||||
|
deadline_start = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = CourseSessionEdoniqTest
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
"course_session_id",
|
||||||
|
"learning_content_id",
|
||||||
|
"deadline_id",
|
||||||
|
"deadline_start",
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_deadline_start(self, obj):
|
||||||
|
if obj.deadline:
|
||||||
|
return obj.deadline.start
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue