Update slugs when parent changes slug due to title change

This commit is contained in:
Daniel Egger 2023-07-24 13:34:08 +02:00
parent 6654d61761
commit a999375f23
6 changed files with 84 additions and 6 deletions

View File

@ -244,6 +244,7 @@ WAGTAIL_PASSWORD_RESET_ENABLED = False
WAGTAILUSERS_PASSWORD_ENABLED = False WAGTAILUSERS_PASSWORD_ENABLED = False
WAGTAIL_ENABLE_UPDATE_CHECK = False WAGTAIL_ENABLE_UPDATE_CHECK = False
WAGTAIL_ENABLE_WHATS_NEW_BANNER = False WAGTAIL_ENABLE_WHATS_NEW_BANNER = False
WAGTAIL_CONTENT_LANGUAGES = LANGUAGES
WAGTAILDOCS_DOCUMENT_MODEL = "media_library.LibraryDocument" WAGTAILDOCS_DOCUMENT_MODEL = "media_library.LibraryDocument"

View File

@ -3,7 +3,6 @@ from datetime import datetime
from dateutil.relativedelta import MO, relativedelta, TH, TU from dateutil.relativedelta import MO, relativedelta, TH, TU
from django.utils import timezone from django.utils import timezone
from slugify import slugify from slugify import slugify
from wagtail.models import Site
from wagtail.rich_text import RichText from wagtail.rich_text import RichText
from vbv_lernwelt.assignment.creators.create_assignments import ( from vbv_lernwelt.assignment.creators.create_assignments import (
@ -34,6 +33,7 @@ from vbv_lernwelt.course.models import (
CourseSession, CourseSession,
CourseSessionUser, CourseSessionUser,
) )
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,
@ -231,7 +231,7 @@ def create_test_course_with_categories(apps=None, schema_editor=None):
course_page = CoursePageFactory( course_page = CoursePageFactory(
title="Test Lehrgang", title="Test Lehrgang",
parent=Site.objects.get(is_default_site=True).root_page, parent=get_wagtail_default_site().root_page,
course=course, course=course,
) )
course.slug = course_page.slug course.slug = course_page.slug

View File

@ -1,7 +1,6 @@
from wagtail.models import Site
from vbv_lernwelt.course.consts import COURSE_VERSICHERUNGSVERMITTLERIN_ID from vbv_lernwelt.course.consts import COURSE_VERSICHERUNGSVERMITTLERIN_ID
from vbv_lernwelt.course.factories import CoursePageFactory from vbv_lernwelt.course.factories import CoursePageFactory
from vbv_lernwelt.course.utils import get_wagtail_default_site
def create_versicherungsvermittlerin_with_categories( def create_versicherungsvermittlerin_with_categories(
@ -43,7 +42,7 @@ def create_versicherungsvermittlerin_with_categories(
course_page = CoursePageFactory( course_page = CoursePageFactory(
title=title, title=title,
parent=Site.objects.get(is_default_site=True).root_page, parent=get_wagtail_default_site().root_page,
course=course, course=course,
) )
course.slug = course_page.slug course.slug = course_page.slug

View File

@ -2,7 +2,8 @@ import enum
import uuid import uuid
from django.db import models from django.db import models
from django.db.models import UniqueConstraint from django.db.models import UniqueConstraint, Value
from django.db.models.functions import Replace
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from grapple.models import GraphQLString from grapple.models import GraphQLString
@ -131,6 +132,30 @@ class CourseBasePage(Page):
def __str__(self): def __str__(self):
return f"{self.title}" return f"{self.title}"
def _update_descendant_slugs(self, old_slug, new_slug):
"""
this method is inspired by `_update_descendant_url_paths` from wagtail Page
"""
Page.objects.filter(path__startswith=self.path).exclude(pk=self.pk).update(
slug=Replace("slug", Value(old_slug), Value(new_slug))
)
def save(self, clean=True, user=None, log_action=False, **kwargs):
slug_changed = False
if not self.id is None:
old_record = Page.objects.get(id=self.id).specific
if old_record.slug != self.slug:
self.set_url_path(self.get_parent())
slug_changed = True
old_slug = old_record.slug
new_slug = self.slug
super().save(**kwargs)
if slug_changed:
self._update_descendant_slugs(old_slug, new_slug)
class CoursePage(CourseBasePage): class CoursePage(CourseBasePage):
content_panels = Page.content_panels content_panels = Page.content_panels

View File

@ -0,0 +1,38 @@
from rest_framework.test import APITestCase
from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.learnpath.models import Circle, LearningContentAttendanceCourse
class CourseBasePageSaveTestCase(APITestCase):
def setUp(self) -> None:
create_default_users()
create_test_course()
def test_save_willRenameSlugsOfChildren(self):
circle_fahrzeug = Circle.objects.get(title="Fahrzeug")
self.assertEqual(circle_fahrzeug.slug, "test-lehrgang-lp-circle-fahrzeug")
lc_attendance_course = LearningContentAttendanceCourse.objects.descendant_of(
circle_fahrzeug
).first()
self.assertEqual(
lc_attendance_course.slug,
"test-lehrgang-lp-circle-fahrzeug-lc-präsenzkurs-fahrzeug",
)
# title update should also update the slugs of the descendants
circle_fahrzeug.title = "Foobar"
circle_fahrzeug.save()
circle_fahrzeug = Circle.objects.get(id=circle_fahrzeug.id)
self.assertEqual(circle_fahrzeug.slug, "test-lehrgang-lp-circle-foobar")
lc_attendance_course = LearningContentAttendanceCourse.objects.descendant_of(
circle_fahrzeug
).first()
self.assertEqual(
lc_attendance_course.slug,
"test-lehrgang-lp-circle-foobar-lc-präsenzkurs-fahrzeug",
)

View File

@ -0,0 +1,15 @@
import wagtail_factories
from django.conf import settings
from wagtail.models import Locale, Site
def get_wagtail_default_site():
for language in settings.WAGTAIL_CONTENT_LANGUAGES:
Locale.objects.get_or_create(language_code=language[0])
site = Site.objects.filter(is_default_site=True).first()
if not site:
site = wagtail_factories.SiteFactory(is_default_site=True)
return site