@@ -830,6 +830,76 @@ def test_inlines_based_on_model_state(self):
830830 parent .refresh_from_db ()
831831 self .assertIs (parent .show_inlines , True )
832832
833+ def test_delete_protected_message_limits_number_of_objects_displayed (self ):
834+ # admin limits the number of displayed objects to 2, so we create
835+ # 5 footnotes.
836+ novel = Novel .objects .create ()
837+ chapter = Chapter .objects .create (novel = novel )
838+ footnotes = [FootNote (chapter = chapter ) for i in range (5 )]
839+ FootNote .objects .bulk_create (footnotes )
840+
841+ response = self .client .post (
842+ reverse ("admin:admin_inlines_novel_change" , args = (novel .pk ,)),
843+ data = {
844+ "show_inlines" : "on" ,
845+ "chapter_set-TOTAL_FORMS" : "1" ,
846+ "chapter_set-INITIAL_FORMS" : "1" ,
847+ "chapter_set-MAX_NUM_FORMS" : "1000" ,
848+ "chapter_set-MIN_NUM_FORMS" : "0" ,
849+ "chapter_set-0-id" : chapter .id ,
850+ "chapter_set-0-name" : chapter .name ,
851+ "chapter_set-0-novel" : novel .id ,
852+ "chapter_set-0-DELETE" : "on" ,
853+ },
854+ )
855+ self .assertEqual (response .status_code , 200 )
856+ inline_formset = response .context_data ["inline_admin_formsets" ][0 ]
857+ self .assertEqual (1 , len (inline_formset .non_form_errors ()))
858+ error_message = inline_formset .non_form_errors ()[0 ]
859+ self .assertTrue (
860+ error_message .startswith (
861+ f"Deleting chapter Chapter object ({ chapter .pk } ) would "
862+ "require deleting the following protected related objects:"
863+ ),
864+ error_message ,
865+ )
866+ self .assertEqual (error_message .count ("FootNote" ), 3 , error_message )
867+ self .assertTrue (error_message .endswith ("…and 2 more objects." ), error_message )
868+
869+ def test_delete_protected_message_does_not_limit_small_amount_of_objects (self ):
870+ novel = Novel .objects .create ()
871+ chapter = Chapter .objects .create (novel = novel )
872+ footnotes = [FootNote (chapter = chapter ) for i in range (3 )]
873+ FootNote .objects .bulk_create (footnotes )
874+
875+ response = self .client .post (
876+ reverse ("admin:admin_inlines_novel_change" , args = (novel .pk ,)),
877+ data = {
878+ "show_inlines" : "on" ,
879+ "chapter_set-TOTAL_FORMS" : "1" ,
880+ "chapter_set-INITIAL_FORMS" : "1" ,
881+ "chapter_set-MAX_NUM_FORMS" : "1000" ,
882+ "chapter_set-MIN_NUM_FORMS" : "0" ,
883+ "chapter_set-0-id" : chapter .id ,
884+ "chapter_set-0-name" : chapter .name ,
885+ "chapter_set-0-novel" : novel .id ,
886+ "chapter_set-0-DELETE" : "on" ,
887+ },
888+ )
889+ self .assertEqual (response .status_code , 200 )
890+ inline_formset = response .context_data ["inline_admin_formsets" ][0 ]
891+ self .assertEqual (1 , len (inline_formset .non_form_errors ()))
892+ error_message = inline_formset .non_form_errors ()[0 ]
893+ self .assertTrue (
894+ error_message .startswith (
895+ f"Deleting chapter Chapter object ({ chapter .pk } ) would require "
896+ "deleting the following protected related objects:"
897+ ),
898+ error_message ,
899+ )
900+ self .assertEqual (error_message .count ("FootNote object" ), 3 )
901+ self .assertNotIn ("more" , error_message )
902+
833903
834904@override_settings (ROOT_URLCONF = "admin_inlines.urls" )
835905class TestInlineMedia (TestDataMixin , TestCase ):
0 commit comments