kopia lustrzana https://github.com/wagtail/wagtail
rodzic
1c7c5cfc0b
commit
0b8a8c2024
|
@ -42,6 +42,7 @@ Changelog
|
|||
* Rename the setting `BASE_URL` (undocumented) to `WAGTAILADMIN_BASE_URL` and add to documentation, `BASE_URL` will be removed in a future release (Sandil Ranasinghe)
|
||||
* Validate to and from email addresses within form builder pages when using `AbstractEmailForm` (Jake Howard)
|
||||
* Add `WAGTAILIMAGES_RENDITION_STORAGE` setting to allow an alternative image rendition storage (Heather White)
|
||||
* Add `wagtail_update_image_renditions` management command to regenerate image renditions or purge all existing renditions (Hitansh Shah, Onno Timmerman, Damian Moore)
|
||||
* Fix: When using `simple_translations` ensure that the user is redirected to the page edit view when submitting for a single locale (Mitchel Cabuloy)
|
||||
* Fix: When previewing unsaved changes to `Form` pages, ensure that all added fields are correctly shown in the preview (Joshua Munn)
|
||||
* Fix: When Documents (e.g. PDFs) have been configured to be served inline via `WAGTAILDOCS_CONTENT_TYPES` & `WAGTAILDOCS_INLINE_CONTENT_TYPES` ensure that the filename is correctly set in the `Content-Disposition` header so that saving the files will use the correct filename (John-Scott Atlakson)
|
||||
|
|
|
@ -587,6 +587,7 @@ Contributors
|
|||
* Sandil Ranasinghe
|
||||
* Caio Jhonny
|
||||
* Heather White
|
||||
* Onno Timmerman
|
||||
|
||||
Translators
|
||||
===========
|
||||
|
|
|
@ -125,3 +125,22 @@ search_garbage_collect
|
|||
$ ./manage.py search_garbage_collect
|
||||
|
||||
Wagtail keeps a log of search queries that are popular on your website. On high traffic websites, this log may get big and you may want to clean out old search queries. This command cleans out all search query logs that are more than one week old (or a number of days configurable through the :ref:`WAGTAILSEARCH_HITS_MAX_AGE <wagtailsearch_hits_max_age>` setting).
|
||||
|
||||
.. _wagtail_update_image_renditions:
|
||||
|
||||
wagtail_update_image_renditions
|
||||
-------------------------------
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ./manage.py wagtail_update_image_renditions
|
||||
|
||||
This command provides the ability to regenerate image renditions.
|
||||
This is useful if you have deployed to a server where the image renditions have not yet been generated or you have changed the underlying image rendition behaviour and need to ensure all renditions are created again.
|
||||
|
||||
This does not remove rendition images that are unused, this can be done by clearing the folder using ``rm -rf`` or similar, once this is done you can then use the management command to generate the renditions.
|
||||
|
||||
Options:
|
||||
|
||||
- **--purge-only** :
|
||||
This argument will purge all image renditions without regenerating them. They will be regenerated when next requested.
|
||||
|
|
|
@ -72,6 +72,7 @@ class LandingPage(Page):
|
|||
* Rename the setting `BASE_URL` (undocumented) to [`WAGTAILADMIN_BASE_URL`](wagtailadmin_base_url) and add to documentation, `BASE_URL` will be removed in a future release (Sandil Ranasinghe)
|
||||
* Validate to and from email addresses within form builder pages when using `AbstractEmailForm` (Jake Howard)
|
||||
* Add [`WAGTAILIMAGES_RENDITION_STORAGE`](wagtailimages_rendition_storage) setting to allow an alternative image rendition storage (Heather White)
|
||||
* Add [`wagtail_update_image_renditions` management command](wagtail_update_image_renditions) to regenerate image renditions or purge all existing renditions (Hitansh Shah, Onno Timmerman, Damian Moore)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
|
|
@ -390,6 +390,14 @@ done from the Django shell:
|
|||
>>> from wagtail.images.models import Rendition
|
||||
>>> Rendition.objects.all().delete()
|
||||
|
||||
You can also directly use the image management command from the console for regenerating the renditions:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ./manage.py wagtail_update_image_renditions --purge
|
||||
|
||||
You can read more about this command from :ref:`wagtail_update_image_renditions`
|
||||
|
||||
Changing per-tag
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
|
||||
from wagtail.images import get_image_model
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Command to create missing image renditions with the option to remove (purge) any existing ones."""
|
||||
|
||||
help = "This command will generate all image renditions, with an option to purge existing renditions first."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--purge-only",
|
||||
action="store_true",
|
||||
help="Purge all image renditions without regenerating them",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
renditions = get_image_model().get_rendition_model().objects.all()
|
||||
if len(renditions) == 0:
|
||||
self.stdout.write("No image renditions found.")
|
||||
return
|
||||
|
||||
success_count = 0
|
||||
if options["purge_only"]:
|
||||
for rendition in renditions:
|
||||
try:
|
||||
rendition_image = rendition.image
|
||||
rendition.delete()
|
||||
success_count = success_count + 1
|
||||
except Exception:
|
||||
self.stderr.write(
|
||||
f"Could not purge rendition for {rendition_image.title}"
|
||||
)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Successfully purged {success_count} image rendition(s)"
|
||||
)
|
||||
)
|
||||
else:
|
||||
for rendition in renditions:
|
||||
try:
|
||||
rendition_filter = rendition.filter
|
||||
rendition_image = rendition.image
|
||||
rendition.delete()
|
||||
rendition_image.get_rendition(rendition_filter)
|
||||
success_count = success_count + 1
|
||||
except Exception:
|
||||
self.stderr.write(
|
||||
f"Could not regenerate rendition for {rendition_image.title}"
|
||||
)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Successfully regenerated {success_count} image rendition(s)"
|
||||
)
|
||||
)
|
|
@ -0,0 +1,89 @@
|
|||
import re
|
||||
from io import StringIO
|
||||
|
||||
from django.core import management
|
||||
from django.test import TestCase
|
||||
|
||||
from wagtail.images import get_image_model
|
||||
|
||||
from .utils import Image, get_test_image_file
|
||||
|
||||
|
||||
class TestUpdateImageRenditions(TestCase):
|
||||
def setUp(self):
|
||||
self.image = Image.objects.create(
|
||||
title="Test image",
|
||||
file=get_test_image_file(filename="test_image.png", colour="white"),
|
||||
)
|
||||
|
||||
self.rendition = Image.get_rendition_model().objects.create(
|
||||
image=self.image,
|
||||
filter_spec="original",
|
||||
width=1000,
|
||||
height=1000,
|
||||
file=get_test_image_file(
|
||||
filename="test_rendition.png", colour="white", size=(1000, 1000)
|
||||
),
|
||||
)
|
||||
|
||||
def delete_renditions(self):
|
||||
renditions = get_image_model().get_rendition_model().objects.all()
|
||||
for rendition in renditions:
|
||||
try:
|
||||
rendition_image = rendition.image
|
||||
rendition.delete()
|
||||
except Exception:
|
||||
print(f"Could not delete rendition for {rendition_image}")
|
||||
|
||||
def run_command(self, **options):
|
||||
output = StringIO()
|
||||
management.call_command(
|
||||
"wagtail_update_image_renditions", stdout=output, **options
|
||||
)
|
||||
output.seek(0)
|
||||
|
||||
return output
|
||||
|
||||
def test_exits_early_for_no_renditions(self):
|
||||
self.delete_renditions()
|
||||
# checking when command is called without any arguments
|
||||
output = self.run_command()
|
||||
self.assertEqual(output.read(), "No image renditions found.\n")
|
||||
|
||||
# checking when command is called with '--purge-only'
|
||||
output = self.run_command(purge_only=True)
|
||||
self.assertEqual(output.read(), "No image renditions found.\n")
|
||||
|
||||
def test_image_renditions(self):
|
||||
renditions = get_image_model().get_rendition_model().objects.all()
|
||||
total_renditions = len(renditions)
|
||||
output = self.run_command()
|
||||
reaesc = re.compile(r"\x1b[^m]*m")
|
||||
output_string = reaesc.sub("", output.read())
|
||||
# checking if the number of renditions regenerated equal total_renditions
|
||||
self.assertEqual(
|
||||
output_string,
|
||||
f"Successfully regenerated {total_renditions} image rendition(s)\n",
|
||||
)
|
||||
|
||||
# checking if the number of renditions now equal total_renditions
|
||||
renditions_now = get_image_model().get_rendition_model().objects.all()
|
||||
total_renditions_now = len(renditions_now)
|
||||
self.assertEqual(total_renditions_now, total_renditions)
|
||||
|
||||
def test_image_renditions_with_purge_only(self):
|
||||
renditions = get_image_model().get_rendition_model().objects.all()
|
||||
total_renditions = len(renditions)
|
||||
output = self.run_command(purge_only=True)
|
||||
reaesc = re.compile(r"\x1b[^m]*m")
|
||||
output_string = reaesc.sub("", output.read())
|
||||
# checking if the number of renditions purged equal total_renditions
|
||||
self.assertEqual(
|
||||
output_string,
|
||||
f"Successfully purged {total_renditions} image rendition(s)\n",
|
||||
)
|
||||
|
||||
# checking if the number of renditions now equal 0
|
||||
renditions_now = get_image_model().get_rendition_model().objects.all()
|
||||
total_renditions_now = len(renditions_now)
|
||||
self.assertEqual(total_renditions_now, 0)
|
Ładowanie…
Reference in New Issue