Skip to content

Commit 3f8cf8c

Browse files
committed
Add command to update blog page types by title
1 parent 1a63521 commit 3f8cf8c

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from django.core.management.base import BaseCommand
2+
3+
from blog.models import BlogPage
4+
5+
6+
class Command(BaseCommand):
7+
help = 'Bulk update blog pages to use another template'
8+
9+
def add_arguments(self, parser):
10+
parser.add_argument(
11+
'--commit',
12+
action='store_true',
13+
help='Commit changes to the database',
14+
)
15+
16+
parser.add_argument(
17+
'select',
18+
metavar='REGEX',
19+
help='Regular expression to select page titles to convert'
20+
)
21+
22+
parser.add_argument(
23+
'template_type',
24+
choices=[choice[0] for choice in BlogPage.BLOG_TEMPLATE_CHOICES],
25+
help='Template type to convert pages to',
26+
)
27+
28+
def handle(self, *args, **options):
29+
select_regex = options['select']
30+
pages = BlogPage.objects.filter(title__regex=select_regex)
31+
selected_count = pages.count()
32+
self.stdout.write(
33+
f'Blog page titles matching {select_regex!r}: {selected_count}'
34+
)
35+
36+
if selected_count < 1:
37+
return
38+
longest_title = max(len(page.title) for page in pages)
39+
top_row = f'{"id":^4} | {"title":^{longest_title}} | current type'
40+
41+
self.stdout.write(top_row)
42+
self.stdout.write('-' * len(top_row))
43+
for i, page in enumerate(pages):
44+
self.stdout.write(f'{page.pk:>4} | {page.title:<{longest_title}} | {page.blog_type}')
45+
page.blog_type = options['template_type']
46+
self.stdout.write('\n')
47+
48+
if options['commit']:
49+
BlogPage.objects.bulk_update(pages, ['blog_type'])
50+
self.stdout.write('Pages updated')

blog/tests/test_commands.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from io import StringIO
2+
3+
from django.core.management import call_command
4+
from django.test import TestCase
5+
from wagtail.models import Site
6+
7+
from ..models import BlogPage
8+
from .factories import (
9+
BlogIndexPageFactory,
10+
BlogPageFactory
11+
)
12+
13+
14+
class ConvertBlogTypeTest(TestCase):
15+
@classmethod
16+
def setUpTestData(cls):
17+
s = Site.objects.get(is_default_site=True)
18+
19+
index = BlogIndexPageFactory(parent=s.root_page)
20+
cls.blog_post = BlogPageFactory(
21+
title='Blog Post 1',
22+
blog_type=BlogPage.DEFAULT,
23+
parent=index,
24+
)
25+
cls.newsletter_post = BlogPageFactory(
26+
title='Newsletter 1',
27+
blog_type=BlogPage.DEFAULT,
28+
parent=index,
29+
)
30+
cls.special_post = BlogPageFactory(
31+
title='Something very special',
32+
blog_type=BlogPage.SPECIAL,
33+
parent=index,
34+
)
35+
36+
def test_output_if_no_pages_match_selection(self):
37+
out = StringIO()
38+
call_command('convert_blog_type', '^XYZ$', 'newsletter', stdout=out)
39+
expected_output = "Blog page titles matching '^XYZ$': 0"
40+
self.assertIn(expected_output, out.getvalue())
41+
42+
def test_output_if_pages_match_selection(self):
43+
out = StringIO()
44+
call_command('convert_blog_type', '^Blog', 'newsletter', stdout=out)
45+
46+
self.assertIn(self.blog_post.title, out.getvalue())
47+
48+
def test_updates_blog_page_type_when_commit_option_given(self):
49+
out = StringIO()
50+
call_command('convert_blog_type', '^News', 'newsletter', commit=True, stdout=out)
51+
52+
self.newsletter_post.refresh_from_db()
53+
self.blog_post.refresh_from_db()
54+
self.special_post.refresh_from_db()
55+
56+
self.assertEqual(self.newsletter_post.blog_type, BlogPage.NEWSLETTER)
57+
self.assertEqual(self.special_post.blog_type, BlogPage.SPECIAL)
58+
self.assertEqual(self.blog_post.blog_type, BlogPage.DEFAULT)

0 commit comments

Comments
 (0)