Rename ModuleCategory -> ModuleLevel

This commit is contained in:
Lorenz Padberg 2023-08-21 14:22:28 +02:00
parent 0648497d50
commit 0b1954c570
18 changed files with 111 additions and 101 deletions

View File

@ -2,9 +2,9 @@
<div class="module-filter"> <div class="module-filter">
<div class="module-filter__filterselection"> <div class="module-filter__filterselection">
<Dropdown class="module-filter__dropdown" <Dropdown class="module-filter__dropdown"
:selected-item="selectedCategory" :selected-item="selectedLevel"
:items="firstLevelCategories" :items="levelOptions"
@update:selectedItem="newItem => selectedCategory = newItem" @update:selectedItem="newItem => selectedLevel = newItem"
></Dropdown> ></Dropdown>
<Dropdown <Dropdown
@ -14,9 +14,9 @@
@update:selectedItem="newItem => selectedLernfeld = newItem" @update:selectedItem="newItem => selectedLernfeld = newItem"
></Dropdown> ></Dropdown>
<pill-radio-buttons :selectableItems="languageOptions" <pill-radio-buttons :selectableItems="languageOptions"
:defaultSelectedItem="initialLanguage" :defaultSelectedItem="initialLanguage"
class="module-filter__language-selection" class="module-filter__language-selection"
@update:selectedItem="item => selectedLanguage = item"/> @update:selectedItem="item => selectedLanguage = item"/>
</div> </div>
<div class="topic__modules"> <div class="topic__modules">
@ -58,9 +58,9 @@
const selectedLanguage = ref(initialLanguage) const selectedLanguage = ref(initialLanguage)
const {result: moduleCategoriesResult} = useQuery(gql` const {result: moduleLevelsResult} = useQuery(gql`
query ModuleCategoriesQuery { query ModuleLevelsQuery {
moduleCategories { moduleLevels {
name name
id id
} }
@ -71,12 +71,12 @@
name: '---', name: '---',
id: null, id: null,
}; };
let defaultCategory = loadDefaultCategory(props.me); let defaultLevel = loadDefaultLevel(props.me);
let selectedCategory = ref(defaultCategory); let selectedLevel = ref(defaultLevel);
const firstLevelCategories = computed(() => { const levelOptions = computed(() => {
return [nullCategory, ...moduleCategoriesResult.value?.moduleCategories || []]; return [nullCategory, ...moduleLevelsResult.value?.moduleLevels || []];
}); });
const nullLernfeld = { const nullLernfeld = {
@ -104,8 +104,8 @@
return filterModules(); return filterModules();
}); });
function loadDefaultCategory(me) { function loadDefaultLevel(me) {
return me?.lastModuleCategory || nullCategory; return me?.lastModuleLevel || nullCategory;
} }
@ -113,14 +113,14 @@
let filteredModules = props.modules; let filteredModules = props.modules;
if (selectedCategory.value === null) { if (selectedLevel.value === null) {
return props.modules; return props.modules;
} }
// filter by Lehrjahr // filter by Lehrjahr
if (selectedCategory.value.name !== '---') { if (selectedLevel.value.name !== '---') {
filteredModules = filteredModules.filter((module) => { filteredModules = filteredModules.filter((module) => {
return module.category?.id == selectedCategory.value.id; return module.level?.id == selectedLevel.value.id;
}); });
} }
@ -130,8 +130,8 @@
return module.categoryType?.id == selectedLernfeld.value.id; return module.categoryType?.id == selectedLernfeld.value.id;
}); });
} }
updateLastModuleCategory(selectedCategory.value); updateLastModuleLevel(selectedLevel.value);
filteredModules = filterByLanguage(selectedLanguage.value, filteredModules); filteredModules = filterByLanguage(selectedLanguage.value, filteredModules);
return filteredModules; return filteredModules;
} }
@ -142,24 +142,23 @@
} }
function updateLastModuleCategory(moduleCategory: Object) { function updateLastModuleLevel(moduleLevel: Object) {
console.log(moduleCategory);
const {mutate: updateLastModuleCategory} = useMutation(gql` const {mutate: updateLastModuleLevel} = useMutation(gql`
mutation ($input: UpdateLastModuleCategoryInput!){updateLastModuleCategory(input: $input) { mutation ($input: UpdateLastModuleLevelInput!){updateLastModuleLevel(input: $input) {
clientMutationId clientMutationId
user { user {
username username
lastModuleCategory { lastModuleLevel {
name name
id id
} }
} }
}}`); }}`);
updateLastModuleCategory({ updateLastModuleLevel({
input: { input: {
id: moduleCategory.id, id: moduleLevel.id,
}, },
}); });

View File

@ -18,7 +18,7 @@
{{ teaser }} {{ teaser }}
</p> </p>
<div class="module-teaser__pills"> <div class="module-teaser__pills">
<pill :text="category?.name"></pill> <pill :text="level?.name"></pill>
<pill :text="categoryType?.name"></pill> <pill :text="categoryType?.name"></pill>
</div> </div>
</div> </div>
@ -30,7 +30,7 @@
export default { export default {
components: {Pill}, components: {Pill},
props: ['metaTitle', 'title', 'teaser', 'id', 'slug', 'heroImage', 'category', 'categoryType'], props: ['metaTitle', 'title', 'teaser', 'id', 'slug', 'heroImage', 'level', 'categoryType'],
computed: { computed: {

View File

@ -9,7 +9,7 @@ fragment ModuleParts on ModuleNode {
heroSource heroSource
solutionsEnabled solutionsEnabled
inEditMode @client inEditMode @client
category { level {
id id
name name
} }

View File

@ -10,7 +10,7 @@ fragment UserParts on PrivateUserNode {
avatarUrl avatarUrl
expiryDate expiryDate
readOnly readOnly
lastModuleCategory { lastModuleLevel {
id id
name name
} }

View File

@ -14,7 +14,7 @@ export interface Me {
team: any; team: any;
lastTopic: any; lastTopic: any;
readOnly: boolean; readOnly: boolean;
lastModuleCategory: any; lastModuleLevel: any;
} }
export interface MeQuery { export interface MeQuery {
@ -45,7 +45,7 @@ const defaultMe: MeQuery = {
team: null, team: null,
readOnly: false, readOnly: false,
lastTopic: undefined, lastTopic: undefined,
lastModuleCategory: undefined, lastModuleLevel: undefined,
}, },
}; };
@ -80,8 +80,8 @@ const getCurrentClassName = (me: Me) => {
return currentClass ? currentClass.name : me.schoolClasses.length ? me.schoolClasses[0].name : ''; return currentClass ? currentClass.name : me.schoolClasses.length ? me.schoolClasses[0].name : '';
}; };
const getLastModuleCategory = (me: Me) => { const getLastModuleLevel = (me: Me) => {
return me.lastModuleCategory; return me.lastModuleLevel;
} }
const getMe = () => { const getMe = () => {
@ -134,9 +134,9 @@ const meMixin = {
// @ts-ignore // @ts-ignore
return getCurrentClassName(this.$data.me); return getCurrentClassName(this.$data.me);
}, },
lastModuleCategory(): any { lastModuleLevel(): any {
// @ts-ignore // @ts-ignore
return getLastModuleCategory(this.$data.me); return getLastModuleLevel(this.$data.me);
} }
}, },

View File

@ -1,4 +1,4 @@
from .models.module import Module, ModuleCategory, ModuleType from .models.module import Module, ModuleLevel, ModuleType
def analyze_module_meta_titles(): def analyze_module_meta_titles():
all_nodes = [] all_nodes = []
@ -19,14 +19,14 @@ def analyze_module_meta_titles():
def create_default_categories(): def create_default_categories():
for lehrjahr in range(1,4): for lehrjahr in range(1,4):
module_category, created = ModuleCategory.objects.get_or_create(name=f"{lehrjahr}. Lehrjahr") module_category, created = ModuleLevel.objects.get_or_create(name=f"{lehrjahr}. Lehrjahr")
for type in range(1, 10): for type in range(1, 10):
ModuleType.objects.get_or_create(name=f"Lernfeld {type}") ModuleType.objects.get_or_create(name=f"Lernfeld {type}")
def categorize_modules(): def categorize_modules():
for category in ModuleCategory.objects.all(): for category in ModuleLevel.objects.all():
modules = Module.objects.filter(category__isnull=True, meta_title__icontains=category.name) modules = Module.objects.filter(category__isnull=True, meta_title__icontains=category.name)
print(f"{category.name}: {modules.count()}") print(f"{category.name}: {modules.count()}")
modules.update(category=category) modules.update(category=category)
@ -39,10 +39,10 @@ def categorize_modules():
def uncategorize_modules(): def uncategorize_modules():
ModuleType.objects.all().delete() ModuleType.objects.all().delete()
ModuleCategory.objects.all().delete() ModuleLevel.objects.all().delete()
def delete_unused_categories(): def delete_unused_categories():
for category in ModuleCategory.objects.all(): for category in ModuleLevel.objects.all():
if not category.module_set.exists(): if not category.module_set.exists():
category.delete() category.delete()

View File

@ -28,7 +28,7 @@ from books.blocks import (
SurveyBlock, SurveyBlock,
VideoBlock, VideoBlock,
) )
from books.models import Book, Chapter, ContentBlock, Module, TextBlock, Topic, ModuleCategory, ModuleType from books.models import Book, Chapter, ContentBlock, Module, TextBlock, Topic, ModuleLevel, ModuleType
from core.factories import ( from core.factories import (
BasePageFactory, BasePageFactory,
DummyImageFactory, DummyImageFactory,
@ -201,9 +201,9 @@ class VideoBlockFactory(wagtail_factories.StructBlockFactory):
class Meta: class Meta:
model = VideoBlock model = VideoBlock
class ModuleCategoryFactory(factory.DjangoModelFactory): class ModuleLevelFactory(factory.DjangoModelFactory):
class Meta: class Meta:
model = ModuleCategory model = ModuleLevel
name = '1. Lehrjahr' name = '1. Lehrjahr'

View File

@ -9,19 +9,19 @@ from core.wagtail_utils import StrictHierarchyPage, get_default_settings
from users.models import SchoolClass from users.models import SchoolClass
from django.utils.text import slugify from django.utils.text import slugify
class ModuleCategory(models.Model): class ModuleLevel(models.Model):
name = models.CharField(max_length=255, unique=True) name = models.CharField(max_length=255, unique=True)
def __str__(self): def __str__(self):
return self.name return self.name
class Meta: class Meta:
verbose_name_plural = _("module categories") verbose_name_plural = _("module Levels")
verbose_name = _("module category") verbose_name = _("module level")
def default_category(): def default_category():
return ModuleCategory.objects.first().pk return ModuleLevel.objects.first().pk
class ModuleType(models.Model): class ModuleType(models.Model):
@ -42,7 +42,7 @@ class Module(StrictHierarchyPage):
verbose_name_plural = "Module" verbose_name_plural = "Module"
meta_title = models.CharField(max_length=255, help_text="e.g. 'Intro' or 'Modul 1'") meta_title = models.CharField(max_length=255, help_text="e.g. 'Intro' or 'Modul 1'")
category = models.ForeignKey(ModuleCategory, on_delete=models.SET_NULL, blank=True, null=True) level = models.ForeignKey(ModuleLevel, on_delete=models.SET_NULL, blank=True, null=True)
category_type = models.ForeignKey(ModuleType, on_delete=models.SET_NULL, blank=True, null=True) category_type = models.ForeignKey(ModuleType, on_delete=models.SET_NULL, blank=True, null=True)
@ -62,12 +62,10 @@ class Module(StrictHierarchyPage):
solutions_enabled_for = models.ManyToManyField(SchoolClass) solutions_enabled_for = models.ManyToManyField(SchoolClass)
# TODO: Filter category_type by category
content_panels = [ content_panels = [
FieldPanel("title", classname="full title"), FieldPanel("title", classname="full title"),
FieldPanel("meta_title", classname="full title"), FieldPanel("meta_title", classname="full title"),
FieldPanel("category"), FieldPanel("level"),
FieldPanel("category_type"), FieldPanel("category_type"),
FieldPanel("hero_image"), FieldPanel("hero_image"),
FieldPanel("hero_source"), FieldPanel("hero_source"),
@ -161,12 +159,6 @@ class Module(StrictHierarchyPage):
def get_admin_display_title(self): def get_admin_display_title(self):
return f"{self.meta_title} - {self.title}" return f"{self.meta_title} - {self.title}"
@property
def category_name(self) -> str:
return self.category.name if self.category else ""
@property
def category_type_name(self) -> str:
return self.category_type.name if self.category_type else ""
class RecentModule(models.Model): class RecentModule(models.Model):

View File

@ -1,7 +1,7 @@
from books.schema.mutations.chapter import UpdateChapterVisibility from books.schema.mutations.chapter import UpdateChapterVisibility
from books.schema.mutations.contentblock import DuplicateContentBlock, MutateContentBlock, AddContentBlock, \ from books.schema.mutations.contentblock import DuplicateContentBlock, MutateContentBlock, AddContentBlock, \
DeleteContentBlock DeleteContentBlock
from books.schema.mutations.module import UpdateSolutionVisibility, UpdateLastModule, SyncModuleVisibility, UpdateLastModuleCategory from books.schema.mutations.module import UpdateSolutionVisibility, UpdateLastModule, SyncModuleVisibility, UpdateLastModuleLevel
from books.schema.mutations.snapshot import CreateSnapshot, ApplySnapshot, ShareSnapshot, UpdateSnapshot, DeleteSnapshot from books.schema.mutations.snapshot import CreateSnapshot, ApplySnapshot, ShareSnapshot, UpdateSnapshot, DeleteSnapshot
from books.schema.mutations.topic import UpdateLastTopic from books.schema.mutations.topic import UpdateLastTopic
@ -14,7 +14,7 @@ class BookMutations(object):
update_solution_visibility = UpdateSolutionVisibility.Field() update_solution_visibility = UpdateSolutionVisibility.Field()
update_last_module = UpdateLastModule.Field() update_last_module = UpdateLastModule.Field()
update_last_topic = UpdateLastTopic.Field() update_last_topic = UpdateLastTopic.Field()
update_last_module_category = UpdateLastModuleCategory.Field() update_last_module_level = UpdateLastModuleLevel.Field()
update_chapter_visibility = UpdateChapterVisibility.Field() update_chapter_visibility = UpdateChapterVisibility.Field()
sync_module_visibility = SyncModuleVisibility.Field() sync_module_visibility = SyncModuleVisibility.Field()
create_snapshot = CreateSnapshot.Field() create_snapshot = CreateSnapshot.Field()

View File

@ -3,7 +3,7 @@ from django.utils import timezone
from graphene import relay from graphene import relay
from api.utils import get_object from api.utils import get_object
from books.models import Module, RecentModule, ModuleCategory from books.models import Module, RecentModule, ModuleLevel
from books.schema.nodes import ModuleNode from books.schema.nodes import ModuleNode
from users.models import SchoolClass, User from users.models import SchoolClass, User
from users.schema import PrivateUserNode from users.schema import PrivateUserNode
@ -105,7 +105,7 @@ class SyncModuleVisibility(relay.ClientIDMutation):
return cls(success=True) return cls(success=True)
class UpdateLastModuleCategory(relay.ClientIDMutation): class UpdateLastModuleLevel(relay.ClientIDMutation):
class Input: class Input:
id = graphene.ID() id = graphene.ID()
@ -115,8 +115,8 @@ class UpdateLastModuleCategory(relay.ClientIDMutation):
def mutate_and_get_payload(cls, root, info, **args): def mutate_and_get_payload(cls, root, info, **args):
user = info.context.user user = info.context.user
id = args.get('id') id = args.get('id')
module_category = get_object(ModuleCategory, id) module_level = get_object(ModuleLevel, id)
User.objects.filter(pk=user.id).update(last_module_category_id=module_category.id) User.objects.filter(pk=user.id).update(last_module_level_id=module_level.id)
return cls(user=user) return cls(user=user)

View File

@ -6,10 +6,10 @@ from graphene_django.filter import DjangoFilterConnectionField
from assignments.models import StudentSubmission from assignments.models import StudentSubmission
from assignments.schema.types import AssignmentNode, StudentSubmissionNode from assignments.schema.types import AssignmentNode, StudentSubmissionNode
from books.models import Module, Chapter, ContentBlock, RecentModule, ModuleCategory, ModuleType from books.models import Module, Chapter, ContentBlock, RecentModule, ModuleLevel, ModuleType
from books.schema.interfaces.module import ModuleInterface from books.schema.interfaces.module import ModuleInterface
from books.schema.nodes.chapter import ChapterNode from books.schema.nodes.chapter import ChapterNode
from books.schema.nodes.module_category import ModuleCategoryNode from books.schema.nodes.module_category import ModuleLevelNode
from books.schema.nodes.module_category_type import ModuleCategoryTypeNode from books.schema.nodes.module_category_type import ModuleCategoryTypeNode
from notes.models import ModuleBookmark, ContentBlockBookmark, ChapterBookmark from notes.models import ModuleBookmark, ContentBlockBookmark, ChapterBookmark
from notes.schema import ( from notes.schema import (
@ -36,7 +36,7 @@ class ModuleNode(DjangoObjectType):
"hero_image", "hero_image",
"hero_source", "hero_source",
"topic", "topic",
"category", "level",
"category_type", "category_type",
] ]
filter_fields = { filter_fields = {
@ -56,7 +56,7 @@ class ModuleNode(DjangoObjectType):
snapshots = graphene.List("books.schema.nodes.SnapshotNode") snapshots = graphene.List("books.schema.nodes.SnapshotNode")
objective_groups = graphene.List(ObjectiveGroupNode) objective_groups = graphene.List(ObjectiveGroupNode)
assignments = graphene.List(AssignmentNode) assignments = graphene.List(AssignmentNode)
category = graphene.Field(ModuleCategoryNode) category = graphene.Field(ModuleLevelNode)
category_type = graphene.Field(ModuleCategoryTypeNode) category_type = graphene.Field(ModuleCategoryTypeNode)
def resolve_chapters(self, info, **kwargs): def resolve_chapters(self, info, **kwargs):
@ -111,7 +111,7 @@ class ModuleNode(DjangoObjectType):
return parent.objective_groups.all().prefetch_related("hidden_for") return parent.objective_groups.all().prefetch_related("hidden_for")
def resolve_category(self, info, **kwargs): def resolve_category(self, info, **kwargs):
return ModuleCategory.objects.get(pk=self.category_id) if self.category_id else None return ModuleLevel.objects.get(pk=self.category_id) if self.category_id else None
def resolve_category_type(self, info, **kwargs): def resolve_category_type(self, info, **kwargs):
return ModuleType.objects.get(pk=self.category_type_id) if self.category_type_id else None return ModuleType.objects.get(pk=self.category_type_id) if self.category_type_id else None

View File

@ -2,12 +2,12 @@ from graphene import relay
from graphene import relay from graphene import relay
from graphene_django import DjangoObjectType from graphene_django import DjangoObjectType
from books.models import ModuleCategory from books.models import ModuleLevel
class ModuleCategoryNode(DjangoObjectType): class ModuleLevelNode(DjangoObjectType):
class Meta: class Meta:
model = ModuleCategory model = ModuleLevel
interfaces = (relay.Node,) interfaces = (relay.Node,)
only_fields = [ only_fields = [
"id", "id",

View File

@ -7,9 +7,9 @@ from core.logger import get_logger
from .connections import TopicConnection, ModuleConnection from .connections import TopicConnection, ModuleConnection
from .nodes import ContentBlockNode, ChapterNode, ModuleNode, NotFoundFailure, SnapshotNode, \ from .nodes import ContentBlockNode, ChapterNode, ModuleNode, NotFoundFailure, SnapshotNode, \
TopicOr404Node TopicOr404Node
from .nodes.module_category import ModuleCategoryNode from .nodes.module_category import ModuleLevelNode
from .nodes.module_category_type import ModuleCategoryTypeNode from .nodes.module_category_type import ModuleCategoryTypeNode
from ..models import Book, Topic, Module, Chapter, Snapshot, ModuleCategory, ModuleType from ..models import Book, Topic, Module, Chapter, Snapshot, ModuleLevel, ModuleType
logger = get_logger(__name__) logger = get_logger(__name__)
@ -27,8 +27,8 @@ class BookQuery(object):
modules = relay.ConnectionField(ModuleConnection) modules = relay.ConnectionField(ModuleConnection)
chapters = DjangoFilterConnectionField(ChapterNode) chapters = DjangoFilterConnectionField(ChapterNode)
module_category = graphene.Field(ModuleCategoryNode, id=graphene.ID(required=True)) module_level = graphene.Field(ModuleLevelNode, id=graphene.ID(required=True))
module_categories = graphene.List(ModuleCategoryNode) module_levels = graphene.List(ModuleLevelNode)
module_category_type= graphene.Field(ModuleCategoryTypeNode, id=graphene.ID(required=True)) module_category_type= graphene.Field(ModuleCategoryTypeNode, id=graphene.ID(required=True))
module_category_types = graphene.List(ModuleCategoryTypeNode) module_category_types = graphene.List(ModuleCategoryTypeNode)
@ -80,18 +80,17 @@ class BookQuery(object):
return None return None
def resolve_module_category(self, info, **kwargs): def resolve_module_level(self, info, **kwargs):
id = kwargs.get('id') module_level_id = kwargs.get('id')
try: try:
if id is not None: if module_level_id is not None:
module_category = get_object(Module, id) return get_object(Module, module_level_id)
return module_category
except Module.DoesNotExist: except Module.DoesNotExist:
return None return None
def resolve_module_categories(self, *args, **kwargs): def resolve_module_levels(self, *args, **kwargs):
return ModuleCategory.objects.filter(**kwargs) return ModuleLevel.objects.filter(**kwargs)
def resolve_module_category_type(self, info, **kwargs): def resolve_module_category_type(self, info, **kwargs):
id = kwargs.get('id') id = kwargs.get('id')

View File

@ -5,7 +5,7 @@ from graphql_relay import to_global_id
from api.schema import schema from api.schema import schema
from api.utils import get_object from api.utils import get_object
from books.models import ContentBlock, Chapter from books.models import ContentBlock, Chapter
from books.factories import ModuleFactory, ModuleCategoryFactory from books.factories import ModuleFactory, ModuleLevelFactory
from core.factories import UserFactory from core.factories import UserFactory
from users.models import User from users.models import User
@ -122,26 +122,26 @@ class NewContentBlockMutationTest(TestCase):
self.assertEqual(content.get('type'), 'image_url_block') self.assertEqual(content.get('type'), 'image_url_block')
self.assertEqual(content.get('value'), {'url': '/test.png'}) self.assertEqual(content.get('value'), {'url': '/test.png'})
def test_updateLastModuleCategory(self): def test_updateLastModuleLevel(self):
self.assertIsNone(self.user.last_module_category, None) self.assertIsNone(self.user.last_module_category, None)
moduleCategory = ModuleCategoryFactory(name='1. Lehrjahr') moduleLevel= ModuleLevelFactory(name='1. Lehrjahr')
moduleCategory1 = ModuleCategoryFactory(name='2. Lehrjahr') moduleLevel1 = ModuleLevelFactory(name='2. Lehrjahr')
mutation = """ mutation = """
mutation ($input: UpdateLastModuleCategoryInput!){updateLastModuleCategory(input: $input) { mutation ($input: UpdateLastModuleLevelInput!){updateLastModuleLevel(input: $input) {
clientMutationId clientMutationId
user { user {
username username
lastModuleCategory { lastModuleLevel {
name name
id id
} }
} }
}} }}
""" """
result = self.client.execute(mutation, variables={"input": {"id": moduleCategory1.id}}) result = self.client.execute(mutation, variables={"input": {"id": moduleLevel1.id}})
self.assertIsNone(result.get('errors')) self.assertIsNone(result.get('errors'))
updated_user = User.objects.get(id=self.user.id) updated_user = User.objects.get(id=self.user.id)
self.assertEqual(updated_user.last_module_category.name, moduleCategory1.name) self.assertEqual(updated_user.last_module_category.name, moduleLevel1.name)

View File

@ -5,19 +5,19 @@ from wagtail.contrib.modeladmin.options import (
) )
from wagtail import hooks from wagtail import hooks
from .models.module import ModuleCategory, ModuleType, Module from .models.module import ModuleLevel, ModuleType, Module
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
class ModuleAdmin(ModelAdmin): class ModuleAdmin(ModelAdmin):
model = Module model = Module
list_display = ("title", "meta_title", "category", "category_type") list_display = ("title", "meta_title", "level", "category_type")
search_fields = ("title", "meta_title") search_fields = ("title", "meta_title")
list_filter = ("category", "category_type") list_filter = ("level", "category_type")
class ModuleCategoryAdmin(ModelAdmin): class ModuleLevelAdmin(ModelAdmin):
model = ModuleCategory model = ModuleLevel
list_display = ("name",) list_display = ("name",)
ordering = ("name",) ordering = ("name",)
@ -33,7 +33,7 @@ class InstrumentGroup(ModelAdminGroup):
menu_label = _("Modules") menu_label = _("Modules")
items = ( items = (
ModuleAdmin, ModuleAdmin,
ModuleCategoryAdmin, ModuleLevelAdmin,
ModuleTypeAdmin, ModuleTypeAdmin,
) )

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.16 on 2023-08-21 12:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('books', '0048_auto_20230821_0922'),
('users', '0033_alter_license_isbn'),
]
operations = [
migrations.AddField(
model_name='user',
name='last_module_level',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='books.modulelevel'),
),
]

View File

@ -33,7 +33,7 @@ class User(AbstractUser):
last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True) last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True)
recent_modules = models.ManyToManyField('books.Module', related_name='+', through='books.RecentModule') recent_modules = models.ManyToManyField('books.Module', related_name='+', through='books.RecentModule')
last_module_category = models.ForeignKey('books.ModuleCategory', related_name='+', on_delete=models.SET_NULL, null=True) last_module_level = models.ForeignKey('books.ModuleLevel', related_name='+', on_delete=models.SET_NULL, null=True)
last_topic = models.ForeignKey('books.Topic', related_name='+', on_delete=models.SET_NULL, null=True) last_topic = models.ForeignKey('books.Topic', related_name='+', on_delete=models.SET_NULL, null=True)
avatar_url = models.CharField(max_length=254, blank=True, default='') avatar_url = models.CharField(max_length=254, blank=True, default='')
email = models.EmailField(_('email address'), unique=True) email = models.EmailField(_('email address'), unique=True)

View File

@ -11,7 +11,7 @@ from graphql_relay import to_global_id
from api.types import FailureNode from api.types import FailureNode
from books.models import Module from books.models import Module
from books.schema.nodes import ModuleCategoryNode from books.schema.nodes import ModuleLevelNode
from books.schema.queries import ModuleNode from books.schema.queries import ModuleNode
from users.models import SchoolClass, SchoolClassMember, Team, User from users.models import SchoolClass, SchoolClassMember, Team, User
@ -104,7 +104,7 @@ class PrivateUserNode(DjangoObjectType):
"onboarding_visited", "onboarding_visited",
"team", "team",
"read_only", "read_only",
"last_module_category" "last_module_level"
] ]
interfaces = (relay.Node,) interfaces = (relay.Node,)