Add LearningUnitQuestion as custom model
This commit is contained in:
parent
4d94f30444
commit
12322638dc
|
|
@ -7,7 +7,7 @@ log.debug('LearningContent.vue setup');
|
||||||
|
|
||||||
const circleStore = useCircleStore();
|
const circleStore = useCircleStore();
|
||||||
|
|
||||||
const questions = computed(() => circleStore.currentSelfEvaluation?.questions);
|
const questions = computed(() => circleStore.currentSelfEvaluation?.children);
|
||||||
let questionIndex = 0;
|
let questionIndex = 0;
|
||||||
const currentQuestion = computed(() => questions.value[questionIndex]);
|
const currentQuestion = computed(() => questions.value[questionIndex]);
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ const currentQuestion = computed(() => questions.value[questionIndex]);
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="mt-8 p-12 border border-gray-500">
|
<div class="mt-8 p-12 border border-gray-500">
|
||||||
<h2 class="heading-2">{{ currentQuestion.value }}</h2>
|
<h2 class="heading-2">{{ currentQuestion.title }}</h2>
|
||||||
|
|
||||||
<div class="mt-12 flex justify-between gap-6">
|
<div class="mt-12 flex justify-between gap-6">
|
||||||
<button class="flex-1 inline-flex items-center text-left p-4 border border-gray-500">
|
<button class="flex-1 inline-flex items-center text-left p-4 border border-gray-500">
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,15 @@ function createEmptyLearningUnit(parentLearningSequence: LearningSequence): Lear
|
||||||
learningContents: [],
|
learningContents: [],
|
||||||
minutes: 0,
|
minutes: 0,
|
||||||
parentLearningSequence: parentLearningSequence,
|
parentLearningSequence: parentLearningSequence,
|
||||||
|
children: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseLearningSequences (children: CircleChild[]): LearningSequence[] {
|
export function parseLearningSequences (children: CircleChild[]): LearningSequence[] {
|
||||||
let learningSequence:LearningSequence | null = null;
|
let learningSequence:LearningSequence | undefined;
|
||||||
let learningUnit:LearningUnit | null = null;
|
let learningUnit:LearningUnit | undefined;
|
||||||
let learningContent:LearningContent | null = null;
|
let learningContent:LearningContent | undefined;
|
||||||
let previousLearningContent: LearningContent | null = null;
|
let previousLearningContent: LearningContent | undefined;
|
||||||
const result:LearningSequence[] = [];
|
const result:LearningSequence[] = [];
|
||||||
|
|
||||||
children.forEach((child) => {
|
children.forEach((child) => {
|
||||||
|
|
@ -35,7 +36,7 @@ export function parseLearningSequences (children: CircleChild[]): LearningSequen
|
||||||
// initialize empty learning unit if there will not come a learning unit next
|
// initialize empty learning unit if there will not come a learning unit next
|
||||||
learningUnit = createEmptyLearningUnit(learningSequence);
|
learningUnit = createEmptyLearningUnit(learningSequence);
|
||||||
} else if (child.type === 'learnpath.LearningUnit') {
|
} else if (child.type === 'learnpath.LearningUnit') {
|
||||||
if (learningSequence === null) {
|
if (!learningSequence) {
|
||||||
throw new Error('LearningUnit found before LearningSequence');
|
throw new Error('LearningUnit found before LearningSequence');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,9 +47,13 @@ export function parseLearningSequences (children: CircleChild[]): LearningSequen
|
||||||
learningUnit = Object.assign(child, {
|
learningUnit = Object.assign(child, {
|
||||||
learningContents: [],
|
learningContents: [],
|
||||||
parentLearningSequence: learningSequence,
|
parentLearningSequence: learningSequence,
|
||||||
|
children: child.children.map((c) => {
|
||||||
|
c.parentLearningUnit = learningUnit;
|
||||||
|
return c;
|
||||||
|
})
|
||||||
});
|
});
|
||||||
} else if (child.type === 'learnpath.LearningContent') {
|
} else if (child.type === 'learnpath.LearningContent') {
|
||||||
if (learningUnit === null) {
|
if (!learningUnit) {
|
||||||
throw new Error('LearningContent found before LearningUnit');
|
throw new Error('LearningContent found before LearningUnit');
|
||||||
}
|
}
|
||||||
previousLearningContent = learningContent;
|
previousLearningContent = learningContent;
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,17 @@ export interface LearningContent extends LearningWagtailPage {
|
||||||
previousLearningContent?: LearningContent;
|
previousLearningContent?: LearningContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LearningUnitQuestion extends LearningWagtailPage {
|
||||||
|
type: 'learnpath.LearningUnitQuestion';
|
||||||
|
parentLearningUnit?: LearningUnit;
|
||||||
|
}
|
||||||
|
|
||||||
export interface LearningUnit extends LearningWagtailPage {
|
export interface LearningUnit extends LearningWagtailPage {
|
||||||
type: 'learnpath.LearningUnit';
|
type: 'learnpath.LearningUnit';
|
||||||
questions: [];
|
|
||||||
learningContents: LearningContent[];
|
learningContents: LearningContent[];
|
||||||
minutes: number;
|
minutes: number;
|
||||||
parentLearningSequence?: LearningSequence;
|
parentLearningSequence?: LearningSequence;
|
||||||
|
children: LearningUnitQuestion[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LearningSequence extends LearningWagtailPage {
|
export interface LearningSequence extends LearningWagtailPage {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Generated by Django 3.2.13 on 2022-06-22 14:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wagtailcore', '0069_log_entry_jsonfield'),
|
||||||
|
('learnpath', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='LearningUnitQuestion',
|
||||||
|
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')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Learning Unit Question',
|
||||||
|
},
|
||||||
|
bases=('wagtailcore.page',),
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='learningcontent',
|
||||||
|
options={'verbose_name': 'Learning Content'},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='learningunit',
|
||||||
|
name='questions',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -100,7 +100,13 @@ class Circle(Page):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_serializer_class(cls):
|
def get_serializer_class(cls):
|
||||||
return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', 'learning_sequences'])
|
return get_it_serializer_class(
|
||||||
|
cls,
|
||||||
|
field_names=[
|
||||||
|
'id', 'title', 'slug', 'type', 'translation_key', 'learning_sequences', 'children',
|
||||||
|
'description', 'job_situations', 'goals', 'experts',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
def full_clean(self, *args, **kwargs):
|
def full_clean(self, *args, **kwargs):
|
||||||
self.slug = find_available_slug(Circle, slugify(self.title, allow_unicode=True))
|
self.slug = find_available_slug(Circle, slugify(self.title, allow_unicode=True))
|
||||||
|
|
@ -144,14 +150,6 @@ class LearningUnit(Page):
|
||||||
parent_page_types = ['learnpath.Circle']
|
parent_page_types = ['learnpath.Circle']
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
|
||||||
questions = StreamField([
|
|
||||||
('question', blocks.CharBlock()),
|
|
||||||
], use_json_field=True)
|
|
||||||
|
|
||||||
content_panels = Page.content_panels + [
|
|
||||||
FieldPanel('questions'),
|
|
||||||
]
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Learning Unit"
|
verbose_name = "Learning Unit"
|
||||||
|
|
||||||
|
|
@ -160,7 +158,22 @@ class LearningUnit(Page):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_serializer_class(cls):
|
def get_serializer_class(cls):
|
||||||
return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', 'questions'])
|
return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', 'children'])
|
||||||
|
|
||||||
|
|
||||||
|
class LearningUnitQuestion(Page):
|
||||||
|
parent_page_types = ['learnpath.LearningUnit']
|
||||||
|
subpage_types = []
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Learning Unit Question"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.title}"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_serializer_class(cls):
|
||||||
|
return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', ])
|
||||||
|
|
||||||
|
|
||||||
class LearningContent(Page):
|
class LearningContent(Page):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import wagtail.api.v2.serializers as wagtail_serializers
|
import wagtail.api.v2.serializers as wagtail_serializers
|
||||||
|
from rest_framework.fields import SerializerMethodField
|
||||||
|
|
||||||
|
|
||||||
def get_it_serializer_class(model, field_names):
|
def get_it_serializer_class(model, field_names):
|
||||||
|
|
@ -13,3 +14,9 @@ class ItTypeField(wagtail_serializers.TypeField):
|
||||||
|
|
||||||
class ItBaseSerializer(wagtail_serializers.BaseSerializer):
|
class ItBaseSerializer(wagtail_serializers.BaseSerializer):
|
||||||
type = ItTypeField(read_only=True)
|
type = ItTypeField(read_only=True)
|
||||||
|
children = SerializerMethodField()
|
||||||
|
|
||||||
|
meta_fields = []
|
||||||
|
|
||||||
|
def get_children(self, obj):
|
||||||
|
return [c.specific.get_serializer_class()(c.specific).data for c in obj.get_children()]
|
||||||
|
|
|
||||||
|
|
@ -4,25 +4,6 @@ from vbv_lernwelt.learnpath.models import Circle, LearningPath
|
||||||
from vbv_lernwelt.learnpath.serializer_helpers import get_it_serializer_class
|
from vbv_lernwelt.learnpath.serializer_helpers import get_it_serializer_class
|
||||||
|
|
||||||
|
|
||||||
class CircleSerializer(get_it_serializer_class(Circle, [])):
|
|
||||||
children = serializers.SerializerMethodField()
|
|
||||||
|
|
||||||
meta_fields = []
|
|
||||||
|
|
||||||
def get_children(self, obj):
|
|
||||||
return [c.specific.get_serializer_class()(c.specific).data for c in obj.get_children()]
|
|
||||||
|
|
||||||
def get_meta_label(self, obj):
|
|
||||||
return obj._meta.label
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Circle
|
|
||||||
fields = [
|
|
||||||
'id', 'title', 'slug', 'type', 'translation_key',
|
|
||||||
'children', 'description', 'job_situations', 'goals', 'experts',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class LearningPathSerializer(get_it_serializer_class(LearningPath, [])):
|
class LearningPathSerializer(get_it_serializer_class(LearningPath, [])):
|
||||||
children = serializers.SerializerMethodField()
|
children = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from vbv_lernwelt.core.admin import User
|
||||||
from vbv_lernwelt.learnpath.models import LearningPath, Topic, Circle, LearningSequence, LearningContent
|
from vbv_lernwelt.learnpath.models import LearningPath, Topic, Circle, LearningSequence, LearningContent
|
||||||
from vbv_lernwelt.learnpath.tests.learning_path_factories import LearningPathFactory, TopicFactory, CircleFactory, \
|
from vbv_lernwelt.learnpath.tests.learning_path_factories import LearningPathFactory, TopicFactory, CircleFactory, \
|
||||||
LearningSequenceFactory, LearningContentFactory, VideoBlockFactory, PodcastBlockFactory, CompetenceBlockFactory, \
|
LearningSequenceFactory, LearningContentFactory, VideoBlockFactory, PodcastBlockFactory, CompetenceBlockFactory, \
|
||||||
ExerciseBlockFactory, DocumentBlockFactory, LearningUnitFactory
|
ExerciseBlockFactory, DocumentBlockFactory, LearningUnitFactory, LearningUnitQuestionFactory
|
||||||
|
|
||||||
|
|
||||||
def create_default_learning_path(user=None):
|
def create_default_learning_path(user=None):
|
||||||
|
|
@ -106,16 +106,17 @@ Fachspezialisten bei.
|
||||||
)
|
)
|
||||||
|
|
||||||
LearningSequenceFactory(title='Beobachten', parent=circe_analyse, icon='it-icon-ls-watch')
|
LearningSequenceFactory(title='Beobachten', parent=circe_analyse, icon='it-icon-ls-watch')
|
||||||
LearningUnitFactory(
|
lu = LearningUnitFactory(
|
||||||
title='Absicherung der Familie',
|
title='Absicherung der Familie',
|
||||||
parent=circe_analyse,
|
parent=circe_analyse,
|
||||||
questions=[{
|
)
|
||||||
"type": "question",
|
LearningUnitQuestionFactory(
|
||||||
"value": "Ich bin in der Lage, mit geeigneten Fragestellungen die Deckung von Versicherungen zu erfassen."
|
title="Ich bin in der Lage, mit geeigneten Fragestellungen die Deckung von Versicherungen zu erfassen.",
|
||||||
}, {
|
parent=lu
|
||||||
"type": "question",
|
)
|
||||||
"value": "Ich weiss was meine Kunden wollen."
|
LearningUnitQuestionFactory(
|
||||||
}]
|
title="Ich weiss was meine Kunden wollen",
|
||||||
|
parent=lu
|
||||||
)
|
)
|
||||||
LearningContentFactory(
|
LearningContentFactory(
|
||||||
title='Ermittlung des Kundenbedarfs',
|
title='Ermittlung des Kundenbedarfs',
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import factory
|
|
||||||
import wagtail_factories
|
import wagtail_factories
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.models import LearningPath, Topic, Circle, LearningSequence, LearningContent, LearningUnit
|
from vbv_lernwelt.learnpath.models import LearningPath, Topic, Circle, LearningSequence, LearningContent, LearningUnit, \
|
||||||
|
LearningUnitQuestion
|
||||||
from vbv_lernwelt.learnpath.models_learning_unit_content import VideoBlock, WebBasedTrainingBlock, PodcastBlock, \
|
from vbv_lernwelt.learnpath.models_learning_unit_content import VideoBlock, WebBasedTrainingBlock, PodcastBlock, \
|
||||||
CompetenceBlock, ExerciseBlock, DocumentBlock, KnowledgeBlock
|
CompetenceBlock, ExerciseBlock, DocumentBlock, KnowledgeBlock
|
||||||
|
|
||||||
|
|
@ -42,8 +42,15 @@ class LearningUnitFactory(wagtail_factories.PageFactory):
|
||||||
model = LearningUnit
|
model = LearningUnit
|
||||||
|
|
||||||
|
|
||||||
|
class LearningUnitQuestionFactory(wagtail_factories.PageFactory):
|
||||||
|
title = 'Frage zu Lerneinheit'
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = LearningUnitQuestion
|
||||||
|
|
||||||
|
|
||||||
class LearningContentFactory(wagtail_factories.PageFactory):
|
class LearningContentFactory(wagtail_factories.PageFactory):
|
||||||
title = "Herzlich Willkommen"
|
title = 'Lerninhalt'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = LearningContent
|
model = LearningContent
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,14 @@ from rest_framework.decorators import api_view
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
|
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
|
||||||
from vbv_lernwelt.learnpath.models import Circle
|
|
||||||
from vbv_lernwelt.learnpath.serializers import CircleSerializer
|
|
||||||
from vbv_lernwelt.learnpath.models import Circle, LearningPath
|
from vbv_lernwelt.learnpath.models import Circle, LearningPath
|
||||||
from vbv_lernwelt.learnpath.serializers import CircleSerializer, LearningPathSerializer
|
from vbv_lernwelt.learnpath.serializers import LearningPathSerializer
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def circle_view(request, slug):
|
def circle_view(request, slug):
|
||||||
circle = Circle.objects.get(slug=slug)
|
circle = Circle.objects.get(slug=slug)
|
||||||
serializer = CircleSerializer(circle)
|
serializer = Circle.get_serializer_class()(circle)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue