From ea53e7c09f1b8864c20c65976bbeaeab77abdaec Mon Sep 17 00:00:00 2001 From: Orhan Hirsch Date: Wed, 26 Apr 2023 09:22:43 +0200 Subject: [PATCH] Fixed #34517 -- Avoided connection post_init signal to ImageField without width/height fields. --- django/db/models/fields/files.py | 9 ++++----- docs/releases/5.0.txt | 3 +++ tests/model_fields/test_imagefield.py | 8 ++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 7f8eb128e1..e10c8cd69a 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -441,7 +441,8 @@ class ImageField(FileField): # after their corresponding image field don't stay cleared by # Model.__init__, see bug #11196. # Only run post-initialization dimension update on non-abstract models - if not cls._meta.abstract: + # with width_field/height_field. + if not cls._meta.abstract and (self.width_field or self.height_field): signals.post_init.connect(self.update_dimension_fields, sender=cls) def update_dimension_fields(self, instance, force=False, *args, **kwargs): @@ -457,10 +458,8 @@ class ImageField(FileField): Dimensions can be forced to update with force=True, which is how ImageFileDescriptor.__set__ calls this method. """ - # Nothing to update if the field doesn't have dimension fields or if - # the field is deferred. - has_dimension_fields = self.width_field or self.height_field - if not has_dimension_fields or self.attname not in instance.__dict__: + # Nothing to update if the field is deferred. + if self.attname not in instance.__dict__: return # getattr will call the ImageFileDescriptor's __get__ method, which diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index dafdc10d62..b1e09dab46 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -379,6 +379,9 @@ Miscellaneous * The undocumented ``Query.annotation_select_mask`` attribute is changed from a set of strings to an ordered list of strings. +* ``ImageField.update_dimension_fields()`` is no longer called on the + ``post_init`` signal if ``width_field`` and ``height_field`` are not set. + .. _deprecated-features-5.0: Features deprecated in 5.0 diff --git a/tests/model_fields/test_imagefield.py b/tests/model_fields/test_imagefield.py index 6ef46ef200..81ac9dad61 100644 --- a/tests/model_fields/test_imagefield.py +++ b/tests/model_fields/test_imagefield.py @@ -5,6 +5,7 @@ from unittest import skipIf from django.core.exceptions import ImproperlyConfigured from django.core.files import File from django.core.files.images import ImageFile +from django.db.models import signals from django.test import TestCase from django.test.testcases import SerializeMixin @@ -328,6 +329,13 @@ class ImageFieldNoDimensionsTests(ImageFieldTwoDimensionsTests): PersonModel = Person + def test_post_init_not_connected(self): + person_model_id = id(self.PersonModel) + self.assertNotIn( + person_model_id, + [sender_id for (_, sender_id), *_ in signals.post_init.receivers], + ) + @skipIf(Image is None, "Pillow is required to test ImageField") class ImageFieldOneDimensionTests(ImageFieldTwoDimensionsTests):