Skip to content

Commit 1569bb9

Browse files
committed
Stopped automatically cleaning up processed images, always
1 parent c597102 commit 1569bb9

File tree

3 files changed

+36
-37
lines changed

3 files changed

+36
-37
lines changed

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ Change log
66
Next version
77
~~~~~~~~~~~~
88

9+
- **Important:** Changed the image field to no longer automatically clean up
10+
processed images when deleting the model instance or when changing the image
11+
field itself. This behavior made it hard to reuse image field values when
12+
copying model data. Instead, processed images are only deleted when the image
13+
file itself is deleted (e.g. using ``object.image.delete()``).
914
- Rewrote ``process_imagefields`` to use the multiprocessing module, which
1015
hopefully improves compatibility on macOS.
1116
- Introduced a ``--no-parallel`` argument to ``process_imagefields``.

imagefield/fields.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,15 @@ def save(self, name, content, save=True): # noqa: FBT002
292292

293293
save.alters_data = True
294294

295+
def delete(self, save=True): # noqa: FBT002
296+
filename = self.name
297+
298+
super().delete(save=save)
299+
300+
self.field._clear_generated_files_for(self, filename)
301+
302+
delete.alters_data = True
303+
295304

296305
def verified(img):
297306
# Anything which exercises the machinery so that we may
@@ -394,27 +403,13 @@ def save_form_data(self, instance, data):
394403
if not data and self.ppoi_field:
395404
setattr(instance, self.ppoi_field, "0.5x0.5")
396405

397-
def _cache_previous(self, instance, **kwargs):
398-
# TODO We still should find a way to cache the previous value.
399-
# See testapp.test_imagefield.Test.test_deferred_imagefields
400-
if self.name in instance.get_deferred_fields():
401-
return
402-
f = getattr(instance, self.name)
403-
setattr(instance, "_previous_%s" % self.name, (f.name, f._ppoi()))
404-
405406
def _generate_files(self, instance, **kwargs):
406407
# Set by the process_imagefields management command
407408
if getattr(instance, "_skip_generate_files", False):
408409
return
409410

410411
f = getattr(instance, self.name)
411412

412-
previous = getattr(instance, "_previous_%s" % self.name, None)
413-
# TODO This will not detect replaced/overwritten files.
414-
if previous and previous[0] and previous != (f.name, f._ppoi()):
415-
logger.info("Clearing generated files for %s", repr(previous))
416-
self._clear_generated_files_for(f, previous[0])
417-
418413
if f.name:
419414
for spec in f.field.formats:
420415
f.process(spec)
@@ -484,16 +479,13 @@ def check(self, **kwargs):
484479
def _register_signal_handlers(sender, **kwargs):
485480
for field in IMAGEFIELDS:
486481
if issubclass(sender, field.model):
487-
signals.post_init.connect(field._cache_previous, sender=sender)
488-
489482
autogenerate = settings.IMAGEFIELD_AUTOGENERATE
490483
if (
491484
autogenerate is True
492485
or autogenerate
493486
and field.field_label in autogenerate
494487
):
495488
signals.post_save.connect(field._generate_files, sender=sender)
496-
signals.post_delete.connect(field._clear_generated_files, sender=sender)
497489

498490

499491
signals.class_prepared.connect(_register_signal_handlers)

tests/testapp/test_imagefield.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,12 @@ def test_model(self):
5555

5656
def test_proxy_model(self):
5757
"""Proxy models should also automatically process images"""
58-
m = Model.objects.create(image="python-logo.png")
59-
self.assertEqual(
60-
contents("__processed__"),
61-
["python-logo-24f8702383e7.png", "python-logo-e6a99ea713c8.png"],
62-
)
63-
m.delete()
64-
self.assertEqual(
65-
contents("__processed__"),
66-
[],
67-
)
6858

69-
m = ProxyModel.objects.create(image="python-logo.png")
59+
ProxyModel.objects.create(image="python-logo.png")
7060
self.assertEqual(
7161
contents("__processed__"),
7262
["python-logo-24f8702383e7.png", "python-logo-e6a99ea713c8.png"],
7363
)
74-
m.delete()
75-
self.assertEqual(
76-
contents("__processed__"),
77-
[],
78-
)
7964

8065
def test_no_ppoi_admin(self):
8166
client = self.login()
@@ -102,7 +87,7 @@ def test_model_with_optional(self):
10287
)
10388

10489
def test_upload(self):
105-
"""Adding and updating images does not leave old thumbs around"""
90+
"""Adding and updating images creates thumbs"""
10691
client = self.login()
10792
self.assertEqual(contents("__processed__"), [])
10893

@@ -136,7 +121,12 @@ def test_upload(self):
136121
self.assertRedirects(response, "/admin/testapp/model/")
137122
self.assertEqual(
138123
contents("__processed__"),
139-
["python-logo-096bade32f42.png", "python-logo-2f5189af7eb3.png"],
124+
[
125+
"python-logo-096bade32f42.png",
126+
"python-logo-24f8702383e7.png",
127+
"python-logo-2f5189af7eb3.png",
128+
"python-logo-e6a99ea713c8.png",
129+
],
140130
)
141131

142132
def test_autorotate(self):
@@ -306,8 +296,6 @@ def spec(fieldfile, context):
306296
"python-logo-e6a99ea713c8.jpg",
307297
],
308298
)
309-
m.delete()
310-
self.assertEqual(contents("__processed__"), [])
311299

312300
def test_adhoc_lowlevel(self):
313301
"""Low-level processing pipelines; no saving of generated images"""
@@ -502,3 +490,17 @@ def test_invalid_ppoi(self):
502490

503491
m.ppoi = None
504492
self.assertEqual(m.image._ppoi(), [0.5, 0.5])
493+
494+
def test_deletion_cleanup(self):
495+
"""Deleting the image file also deletes processed images"""
496+
with openimage("python-logo.png") as f:
497+
m = Model()
498+
m.image.save("stuff.png", ContentFile(f.read()), save=True)
499+
500+
self.assertEqual(
501+
contents("__processed__"),
502+
["stuff-24f8702383e7.png", "stuff-e6a99ea713c8.png"],
503+
)
504+
505+
m.image.delete()
506+
self.assertEqual(contents("__processed__"), [])

0 commit comments

Comments
 (0)