From f88a85a54f83cfa4d8cbf5f7e57a31c98855cdf9 Mon Sep 17 00:00:00 2001 From: Lorenz Padberg Date: Mon, 24 Jul 2023 16:47:37 +0200 Subject: [PATCH] Add module category to cms --- server/books/categorize_modules.py | 38 ++++++++++++-- .../management/commands/categorize_modules.py | 12 +++-- .../create_default_model_categories.py | 11 +++++ server/books/models/module.py | 45 ++++++++++++++++- server/books/wagtail_hooks.py | 49 +++++++++++++++++++ 5 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 server/books/management/commands/create_default_model_categories.py create mode 100644 server/books/wagtail_hooks.py diff --git a/server/books/categorize_modules.py b/server/books/categorize_modules.py index 94a81c02..8847b70c 100644 --- a/server/books/categorize_modules.py +++ b/server/books/categorize_modules.py @@ -1,7 +1,6 @@ -from books.models import Module -import json +from .models.module import Module, ModuleCategory, ModuleType -def categorize_modules(): +def analyze_module_meta_titles(): all_nodes = [] for module in Module.objects.all(): @@ -18,3 +17,36 @@ def categorize_modules(): print(f"{i}.: {set(leafs)}") +def create_default_categories(): + for lehrjahr in range(1,4): + module_category, created = ModuleCategory.objects.get_or_create(name=f"{lehrjahr}. Lehrjahr") + + for type in range(1, 10): + ModuleType.objects.get_or_create(name=f"Lernfeld {type}", category=module_category) + + +def categorize_modules(): + for category in ModuleCategory.objects.all(): + modules = Module.objects.filter(category__isnull=True, category_type__isnull=True, meta_title__icontains=category.name) + print(f"{category.name}: {modules.count()}") + modules.update(category=category) + + for type in ModuleType.objects.all(): + modules = Module.objects.filter(category=type.category, category_type__isnull=True, meta_title__contains=type.name) + print(f"{type.category} {type.name}: {modules.count()}") + modules.update(category_type=type) + + +def uncategorize_modules(): + ModuleCategory.objects.all().delete() + ModuleType.objects.all().delete() + +def delete_unused_categories(): + for category in ModuleCategory.objects.all(): + if not category.module_set.exists(): + category.delete() + +def delete_unused_types(): + for type in ModuleType.objects.all(): + if not type.module_set.exists(): + type.delete() diff --git a/server/books/management/commands/categorize_modules.py b/server/books/management/commands/categorize_modules.py index 934b90c8..fcbc5d76 100644 --- a/server/books/management/commands/categorize_modules.py +++ b/server/books/management/commands/categorize_modules.py @@ -1,11 +1,17 @@ from django.core.management import BaseCommand -from books.categorize_modules import categorize_modules +from books.categorize_modules import categorize_modules, delete_unused_categories, delete_unused_types + +from books.categorize_modules import create_default_categories class Command(BaseCommand): def handle(self, *args, **options): - self.stdout.write("Migrating Wagtail documents to Custommyskillbox documents") + self.stdout.write("Categorizing modules") + create_default_categories() categorize_modules() - self.stdout.write("Finish migration") + delete_unused_types() + delete_unused_categories() + + self.stdout.write("Finish categorizing modules") diff --git a/server/books/management/commands/create_default_model_categories.py b/server/books/management/commands/create_default_model_categories.py new file mode 100644 index 00000000..1b378ce3 --- /dev/null +++ b/server/books/management/commands/create_default_model_categories.py @@ -0,0 +1,11 @@ +from django.core.management import BaseCommand +from books.categorize_modules import categorize_modules, create_default_categories + + +class Command(BaseCommand): + def handle(self, *args, **options): + self.stdout.write("Create defaut categories") + create_default_categories() + self.stdout.write("Finish") + + diff --git a/server/books/models/module.py b/server/books/models/module.py index 180fc0ef..eb39a30e 100644 --- a/server/books/models/module.py +++ b/server/books/models/module.py @@ -1,12 +1,46 @@ from django.db import models from django.utils import timezone -from wagtail.admin.panels import FieldPanel, InlinePanel, TabbedInterface, ObjectList +from wagtail.admin.panels import FieldPanel, InlinePanel, TabbedInterface, ObjectList, MultiFieldPanel, MultipleChooserPanel from wagtail.fields import RichTextField from django.utils.translation import gettext_lazy as _ from core.constants import DEFAULT_RICH_TEXT_FEATURES from core.wagtail_utils import StrictHierarchyPage, get_default_settings from users.models import SchoolClass +from django.utils.text import slugify + +class ModuleCategory(models.Model): + name = models.CharField(max_length=255, unique=True) + + def __str__(self): + return self.name + + class Meta: + verbose_name_plural = _("module categories") + verbose_name = _("module category") + + +def default_category(): + return ModuleCategory.objects.first().pk + + +class ModuleType(models.Model): + class Meta: + verbose_name = _("module type") + verbose_name_plural = _("module types") + ordering = ("category", "name") + + name = models.CharField(max_length=255) + category = models.ForeignKey( + ModuleCategory, + on_delete=models.PROTECT, + null=False, + default=default_category, + related_name="module_types", + ) + + def __str__(self): + return f"{self.category} - {self.name}" class Module(StrictHierarchyPage): @@ -15,6 +49,10 @@ class Module(StrictHierarchyPage): verbose_name_plural = "Module" meta_title = models.CharField(max_length=255, help_text="e.g. 'Intro' or 'Modul 1'") + category = models.ForeignKey(ModuleCategory, on_delete=models.SET_NULL, null=True) + category_type = models.ForeignKey(ModuleType, on_delete=models.SET_NULL, null=True) + + hero_image = models.ForeignKey( "wagtailimages.Image", null=True, @@ -31,13 +69,18 @@ class Module(StrictHierarchyPage): solutions_enabled_for = models.ManyToManyField(SchoolClass) + # TODO: Filter category_type by category + content_panels = [ FieldPanel("title", classname="full title"), FieldPanel("meta_title", classname="full title"), + FieldPanel("category"), + FieldPanel("category_type"), FieldPanel("hero_image"), FieldPanel("hero_source"), FieldPanel("teaser"), FieldPanel("intro"), + # TODO: Why is this commented out? # InlinePanel( # "assignments", # label=_("Assignment"), diff --git a/server/books/wagtail_hooks.py b/server/books/wagtail_hooks.py new file mode 100644 index 00000000..19135580 --- /dev/null +++ b/server/books/wagtail_hooks.py @@ -0,0 +1,49 @@ +from wagtail.contrib.modeladmin.options import ( + ModelAdmin, + ModelAdminGroup, + modeladmin_register, +) +from wagtail import hooks + +from .models.module import ModuleCategory, ModuleType, Module +from django.utils.translation import gettext_lazy as _ + +class ModuleAdmin(ModelAdmin): + model = Module + list_display = ("title", "meta_title", "category", "category_type") + search_fields = ("title", "meta_title") + list_filter = ("category","category_type") + + +class ModuleCategoryAdmin(ModelAdmin): + model = ModuleCategory + list_display = ("name",) + ordering = ("name",) + + +class ModuleTypeAdmin(ModelAdmin): + model = ModuleType + list_display = ( + "name", + "category", + ) + list_filter = ("category",) + ordering = ("category", "name") + inspect_view_enabled = True + inspect_view_fields = ( + "name", + "category", + ) + + +class InstrumentGroup(ModelAdminGroup): + menu_label = _("Modules") + items = ( + ModuleAdmin, + ModuleCategoryAdmin, + ModuleTypeAdmin, + ) + + +modeladmin_register(InstrumentGroup) +