@@ -171,6 +171,54 @@ class Meta:
171171
172172 assert not luke .picture
173173
174+ @pytest .mark .django_db
175+ def test_update_pictures__with_empty_pictures (
176+ self , request , stub_worker , image_upload_file
177+ ):
178+ """Test that update_pictures skips objects with empty/null pictures."""
179+
180+ class ToModel (models .Model ):
181+ name = models .CharField (max_length = 100 )
182+ picture = PictureField (
183+ upload_to = "testapp/profile/" , aspect_ratios = [None , "21/9" ], blank = True
184+ )
185+
186+ class Meta :
187+ app_label = request .node .name
188+ db_table = "testapp_profile"
189+
190+ # Create profiles with different picture states
191+ luke = Profile .objects .create (name = "Luke" , picture = image_upload_file )
192+ leia = Profile .objects .create (name = "Leia" , picture = "" )
193+ han = Profile .objects .create (name = "Han" , picture = None )
194+ stub_worker .join ()
195+
196+ path = luke .picture .aspect_ratios ["16/9" ]["AVIF" ][100 ].path
197+ assert path .exists ()
198+
199+ migration = migrations .AlterPictureField ("profile" , "picture" , PictureField ())
200+ from_field = Profile ._meta .get_field ("picture" )
201+
202+ # This should not fail despite empty/null pictures
203+ migration .update_pictures (from_field , ToModel )
204+ stub_worker .join ()
205+
206+ # Verify old path was deleted and new one was created for luke
207+ assert not path .exists ()
208+ luke .refresh_from_db ()
209+ path = (
210+ ToModel .objects .get (pk = luke .pk )
211+ .picture .aspect_ratios ["21/9" ]["AVIF" ][100 ]
212+ .path
213+ )
214+ assert path .exists ()
215+
216+ # Verify empty profiles still exist and remain empty
217+ leia_profile = Profile .objects .get (pk = leia .pk )
218+ assert not leia_profile .picture
219+ han_profile = Profile .objects .get (pk = han .pk )
220+ assert not han_profile .picture
221+
174222 @pytest .mark .django_db
175223 def test_from_picture_field (self , stub_worker , image_upload_file ):
176224 luke = Profile .objects .create (name = "Luke" , picture = image_upload_file )
@@ -182,6 +230,30 @@ def test_from_picture_field(self, stub_worker, image_upload_file):
182230 stub_worker .join ()
183231 assert not path .exists ()
184232
233+ @pytest .mark .django_db
234+ def test_from_picture_field__with_empty_pictures (
235+ self , stub_worker , image_upload_file
236+ ):
237+ """Test that from_picture_field skips objects with empty/null pictures."""
238+ # Create profiles with different picture states
239+ luke = Profile .objects .create (name = "Luke" , picture = image_upload_file )
240+ Profile .objects .create (name = "Leia" , picture = "" )
241+ Profile .objects .create (name = "Han" , picture = None )
242+ stub_worker .join ()
243+
244+ path = luke .picture .aspect_ratios ["16/9" ]["AVIF" ][100 ].path
245+ assert path .exists ()
246+
247+ migration = migrations .AlterPictureField ("profile" , "picture" , PictureField ())
248+ # This should not fail despite empty/null pictures
249+ migration .from_picture_field (Profile )
250+ stub_worker .join ()
251+
252+ assert not path .exists ()
253+ # Verify other profiles still exist and weren't affected
254+ assert Profile .objects .filter (name = "Leia" ).exists ()
255+ assert Profile .objects .filter (name = "Han" ).exists ()
256+
185257 @pytest .mark .django_db
186258 def test_to_picture_field (self , request , stub_worker , image_upload_file ):
187259 class FromModel (models .Model ):
@@ -234,6 +306,53 @@ class Meta:
234306 migration = migrations .AlterPictureField ("profile" , "picture" , PictureField ())
235307 migration .to_picture_field (FromModel , Profile )
236308
309+ @pytest .mark .django_db
310+ def test_to_picture_field__with_empty_pictures (
311+ self , request , stub_worker , image_upload_file
312+ ):
313+ """Test that to_picture_field skips objects with empty/null pictures."""
314+
315+ class FromModel (models .Model ):
316+ picture = models .ImageField (blank = True )
317+
318+ class Meta :
319+ app_label = request .node .name
320+ db_table = "testapp_profile"
321+
322+ class ToModel (models .Model ):
323+ name = models .CharField (max_length = 100 )
324+ picture = models .ImageField (upload_to = "testapp/profile/" , blank = True )
325+
326+ class Meta :
327+ app_label = request .node .name
328+ db_table = "testapp_profile"
329+
330+ # Create profiles with different picture states
331+ luke = ToModel .objects .create (name = "Luke" , picture = image_upload_file )
332+ leia = ToModel .objects .create (name = "Leia" , picture = "" )
333+ han = ToModel .objects .create (name = "Han" , picture = None )
334+ stub_worker .join ()
335+
336+ migration = migrations .AlterPictureField ("profile" , "picture" , PictureField ())
337+ # This should not fail despite empty/null pictures
338+ migration .to_picture_field (FromModel , Profile )
339+ stub_worker .join ()
340+
341+ luke .refresh_from_db ()
342+ # Verify only luke's picture was processed
343+ path = (
344+ Profile .objects .get (pk = luke .pk )
345+ .picture .aspect_ratios ["16/9" ]["AVIF" ][100 ]
346+ .path
347+ )
348+ assert path .exists ()
349+
350+ # Verify empty profiles still exist
351+ leia_profile = Profile .objects .get (pk = leia .pk )
352+ assert not leia_profile .picture
353+ han_profile = Profile .objects .get (pk = han .pk )
354+ assert not han_profile .picture
355+
237356 @pytest .mark .django_db
238357 def test_to_picture_field__from_stdimage (
239358 self , request , stub_worker , image_upload_file
0 commit comments