mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixed #25374 -- Made ModelAdmin checks work on instances instead of classes.
This allows dynamically-generated attributes to be specified in checked ModelAdmin attributes without triggering errors.
This commit is contained in:
		| @@ -2,6 +2,7 @@ from __future__ import unicode_literals | ||||
|  | ||||
| from django import forms | ||||
| from django.contrib import admin | ||||
| from django.contrib.admin import AdminSite | ||||
| from django.contrib.contenttypes.admin import GenericStackedInline | ||||
| from django.core import checks | ||||
| from django.test import SimpleTestCase, override_settings | ||||
| @@ -32,8 +33,7 @@ class ValidFormFieldsets(admin.ModelAdmin): | ||||
|  | ||||
|  | ||||
| class MyAdmin(admin.ModelAdmin): | ||||
|     @classmethod | ||||
|     def check(cls, model, **kwargs): | ||||
|     def check(self, **kwargs): | ||||
|         return ['error!'] | ||||
|  | ||||
|  | ||||
| @@ -73,7 +73,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             list_editable = ["original_release"] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'list_editable[0]' refers to 'original_release', " | ||||
| @@ -95,8 +95,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                     "fields": ["title", "original_release"], | ||||
|                 }), | ||||
|             ] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("The value of 'list_editable[0]' refers to 'original_release', " | ||||
| @@ -118,15 +117,14 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                 }), | ||||
|             ] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_custom_modelforms_with_fields_fieldsets(self): | ||||
|         """ | ||||
|         # Regression test for #8027: custom ModelForms with fields/fieldsets | ||||
|         """ | ||||
|  | ||||
|         errors = ValidFields.check(model=Song) | ||||
|         errors = ValidFields(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_custom_get_form_with_fieldsets(self): | ||||
| @@ -135,8 +133,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         is overridden. | ||||
|         Refs #19445. | ||||
|         """ | ||||
|  | ||||
|         errors = ValidFormFieldsets.check(model=Song) | ||||
|         errors = ValidFormFieldsets(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_fieldsets_fields_non_tuple(self): | ||||
| @@ -152,7 +149,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                 }), | ||||
|             ] | ||||
|  | ||||
|         errors = NotATupleAdmin.check(model=Song) | ||||
|         errors = NotATupleAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'fieldsets[0][1]['fields']' must be a list or tuple.", | ||||
| @@ -177,7 +174,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                 }), | ||||
|             ] | ||||
|  | ||||
|         errors = NotATupleAdmin.check(model=Song) | ||||
|         errors = NotATupleAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'fieldsets[1][1]['fields']' must be a list or tuple.", | ||||
| @@ -192,11 +189,10 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         """ | ||||
|         Tests for basic system checks of 'exclude' option values (#12689) | ||||
|         """ | ||||
|  | ||||
|         class ExcludedFields1(admin.ModelAdmin): | ||||
|             exclude = 'foo' | ||||
|  | ||||
|         errors = ExcludedFields1.check(model=Book) | ||||
|         errors = ExcludedFields1(Book, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'exclude' must be a list or tuple.", | ||||
| @@ -211,7 +207,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class ExcludedFields2(admin.ModelAdmin): | ||||
|             exclude = ('name', 'name') | ||||
|  | ||||
|         errors = ExcludedFields2.check(model=Book) | ||||
|         errors = ExcludedFields2(Book, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'exclude' contains duplicate field(s).", | ||||
| @@ -231,7 +227,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|             model = Album | ||||
|             inlines = [ExcludedFieldsInline] | ||||
|  | ||||
|         errors = ExcludedFieldsAlbumAdmin.check(model=Album) | ||||
|         errors = ExcludedFieldsAlbumAdmin(Album, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'exclude' must be a list or tuple.", | ||||
| @@ -247,7 +243,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         Regression test for #9932 - exclude in InlineModelAdmin should not | ||||
|         contain the ForeignKey field used in ModelAdmin.model | ||||
|         """ | ||||
|  | ||||
|         class SongInline(admin.StackedInline): | ||||
|             model = Song | ||||
|             exclude = ['album'] | ||||
| @@ -256,7 +251,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|             model = Album | ||||
|             inlines = [SongInline] | ||||
|  | ||||
|         errors = AlbumAdmin.check(model=Album) | ||||
|         errors = AlbumAdmin(Album, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("Cannot exclude the field 'album', because it is the foreign key " | ||||
| @@ -273,14 +268,13 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         Regression test for #22034 - check that generic inlines don't look for | ||||
|         normal ForeignKey relations. | ||||
|         """ | ||||
|  | ||||
|         class InfluenceInline(GenericStackedInline): | ||||
|             model = Influence | ||||
|  | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             inlines = [InfluenceInline] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_generic_inline_model_admin_non_generic_model(self): | ||||
| @@ -288,14 +282,13 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         Ensure that a model without a GenericForeignKey raises problems if it's included | ||||
|         in an GenericInlineModelAdmin definition. | ||||
|         """ | ||||
|  | ||||
|         class BookInline(GenericStackedInline): | ||||
|             model = Book | ||||
|  | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             inlines = [BookInline] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "'admin_checks.Book' has no GenericForeignKey.", | ||||
| @@ -308,7 +301,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|  | ||||
|     def test_generic_inline_model_admin_bad_ct_field(self): | ||||
|         "A GenericInlineModelAdmin raises problems if the ct_field points to a non-existent field." | ||||
|  | ||||
|         class InfluenceInline(GenericStackedInline): | ||||
|             model = Influence | ||||
|             ct_field = 'nonexistent' | ||||
| @@ -316,7 +308,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             inlines = [InfluenceInline] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "'ct_field' references 'nonexistent', which is not a field on 'admin_checks.Influence'.", | ||||
| @@ -329,7 +321,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|  | ||||
|     def test_generic_inline_model_admin_bad_fk_field(self): | ||||
|         "A GenericInlineModelAdmin raises problems if the ct_fk_field points to a non-existent field." | ||||
|  | ||||
|         class InfluenceInline(GenericStackedInline): | ||||
|             model = Influence | ||||
|             ct_fk_field = 'nonexistent' | ||||
| @@ -337,7 +328,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             inlines = [InfluenceInline] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "'ct_fk_field' references 'nonexistent', which is not a field on 'admin_checks.Influence'.", | ||||
| @@ -350,7 +341,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|  | ||||
|     def test_generic_inline_model_admin_non_gfk_ct_field(self): | ||||
|         "A GenericInlineModelAdmin raises problems if the ct_field points to a field that isn't part of a GenericForeignKey" | ||||
|  | ||||
|         class InfluenceInline(GenericStackedInline): | ||||
|             model = Influence | ||||
|             ct_field = 'name' | ||||
| @@ -358,7 +348,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             inlines = [InfluenceInline] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "'admin_checks.Influence' has no GenericForeignKey using content type field 'name' and object ID field 'object_id'.", | ||||
| @@ -371,7 +361,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|  | ||||
|     def test_generic_inline_model_admin_non_gfk_fk_field(self): | ||||
|         "A GenericInlineModelAdmin raises problems if the ct_fk_field points to a field that isn't part of a GenericForeignKey" | ||||
|  | ||||
|         class InfluenceInline(GenericStackedInline): | ||||
|             model = Influence | ||||
|             ct_fk_field = 'name' | ||||
| @@ -379,7 +368,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             inlines = [InfluenceInline] | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "'admin_checks.Influence' has no GenericForeignKey using content type field 'content_type' and object ID field 'name'.", | ||||
| @@ -394,11 +383,10 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         """ | ||||
|         Regression test for #15669 - Include app label in admin system check messages | ||||
|         """ | ||||
|  | ||||
|         class RawIdNonexistingAdmin(admin.ModelAdmin): | ||||
|             raw_id_fields = ('nonexisting',) | ||||
|  | ||||
|         errors = RawIdNonexistingAdmin.check(model=Album) | ||||
|         errors = RawIdNonexistingAdmin(Album, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("The value of 'raw_id_fields[0]' refers to 'nonexisting', which is " | ||||
| @@ -416,7 +404,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         given) make sure fk_name is honored or things blow up when there is more | ||||
|         than one fk to the parent model. | ||||
|         """ | ||||
|  | ||||
|         class TwoAlbumFKAndAnEInline(admin.TabularInline): | ||||
|             model = TwoAlbumFKAndAnE | ||||
|             exclude = ("e",) | ||||
| @@ -425,7 +412,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class MyAdmin(admin.ModelAdmin): | ||||
|             inlines = [TwoAlbumFKAndAnEInline] | ||||
|  | ||||
|         errors = MyAdmin.check(model=Album) | ||||
|         errors = MyAdmin(Album, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_inline_self_check(self): | ||||
| @@ -435,7 +422,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class MyAdmin(admin.ModelAdmin): | ||||
|             inlines = [TwoAlbumFKAndAnEInline] | ||||
|  | ||||
|         errors = MyAdmin.check(model=Album) | ||||
|         errors = MyAdmin(Album, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "'admin_checks.TwoAlbumFKAndAnE' has more than one ForeignKey to 'admin_checks.Album'.", | ||||
| @@ -454,14 +441,14 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class MyAdmin(admin.ModelAdmin): | ||||
|             inlines = [TwoAlbumFKAndAnEInline] | ||||
|  | ||||
|         errors = MyAdmin.check(model=Album) | ||||
|         errors = MyAdmin(Album, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_readonly(self): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             readonly_fields = ("title",) | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_readonly_on_method(self): | ||||
| @@ -471,7 +458,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             readonly_fields = (my_function,) | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_readonly_on_modeladmin(self): | ||||
| @@ -481,21 +468,35 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|             def readonly_method_on_modeladmin(self, obj): | ||||
|                 pass | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_readonly_dynamic_attribute_on_modeladmin(self): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             readonly_fields = ("dynamic_method",) | ||||
|  | ||||
|             def __getattr__(self, item): | ||||
|                 if item == "dynamic_method": | ||||
|                     def method(obj): | ||||
|                         pass | ||||
|                     return method | ||||
|                 raise AttributeError | ||||
|  | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_readonly_method_on_model(self): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             readonly_fields = ("readonly_method_on_model",) | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_nonexistent_field(self): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             readonly_fields = ("title", "nonexistent") | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("The value of 'readonly_fields[1]' is not a callable, an attribute " | ||||
| @@ -512,7 +513,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|             model = City | ||||
|             readonly_fields = ['i_dont_exist']  # Missing attribute | ||||
|  | ||||
|         errors = CityInline.check(State) | ||||
|         errors = CityInline(State, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("The value of 'readonly_fields[0]' is not a callable, an attribute " | ||||
| @@ -531,14 +532,14 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                     return "Best Ever!" | ||||
|                 return "Status unknown." | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_readonly_lambda(self): | ||||
|         class SongAdmin(admin.ModelAdmin): | ||||
|             readonly_fields = (lambda obj: "test",) | ||||
|  | ||||
|         errors = SongAdmin.check(model=Song) | ||||
|         errors = SongAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_graceful_m2m_fail(self): | ||||
| @@ -547,11 +548,10 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         specifies the 'through' option is included in the 'fields' or the 'fieldsets' | ||||
|         ModelAdmin options. | ||||
|         """ | ||||
|  | ||||
|         class BookAdmin(admin.ModelAdmin): | ||||
|             fields = ['authors'] | ||||
|  | ||||
|         errors = BookAdmin.check(model=Book) | ||||
|         errors = BookAdmin(Book, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("The value of 'fields' cannot include the ManyToManyField 'authors', " | ||||
| @@ -570,7 +570,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                 ('Header 2', {'fields': ('authors',)}), | ||||
|             ) | ||||
|  | ||||
|         errors = FieldsetBookAdmin.check(model=Book) | ||||
|         errors = FieldsetBookAdmin(Book, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 ("The value of 'fieldsets[1][1][\"fields\"]' cannot include the ManyToManyField " | ||||
| @@ -586,7 +586,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         class NestedFieldsAdmin(admin.ModelAdmin): | ||||
|             fields = ('price', ('name', 'subtitle')) | ||||
|  | ||||
|         errors = NestedFieldsAdmin.check(model=Book) | ||||
|         errors = NestedFieldsAdmin(Book, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_nested_fieldsets(self): | ||||
| @@ -595,7 +595,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                 ('Main', {'fields': ('price', ('name', 'subtitle'))}), | ||||
|             ) | ||||
|  | ||||
|         errors = NestedFieldsetAdmin.check(model=Book) | ||||
|         errors = NestedFieldsetAdmin(Book, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_explicit_through_override(self): | ||||
| @@ -604,14 +604,13 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         is specified as a string, the admin should still be able use | ||||
|         Model.m2m_field.through | ||||
|         """ | ||||
|  | ||||
|         class AuthorsInline(admin.TabularInline): | ||||
|             model = Book.authors.through | ||||
|  | ||||
|         class BookAdmin(admin.ModelAdmin): | ||||
|             inlines = [AuthorsInline] | ||||
|  | ||||
|         errors = BookAdmin.check(model=Book) | ||||
|         errors = BookAdmin(Book, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_non_model_fields(self): | ||||
| @@ -619,7 +618,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         Regression for ensuring ModelAdmin.fields can contain non-model fields | ||||
|         that broke with r11737 | ||||
|         """ | ||||
|  | ||||
|         class SongForm(forms.ModelForm): | ||||
|             extra_data = forms.CharField() | ||||
|  | ||||
| @@ -627,7 +625,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|             form = SongForm | ||||
|             fields = ['title', 'extra_data'] | ||||
|  | ||||
|         errors = FieldsOnFormOnlyAdmin.check(model=Song) | ||||
|         errors = FieldsOnFormOnlyAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_non_model_first_field(self): | ||||
| @@ -635,7 +633,6 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         Regression for ensuring ModelAdmin.field can handle first elem being a | ||||
|         non-model field (test fix for UnboundLocalError introduced with r16225). | ||||
|         """ | ||||
|  | ||||
|         class SongForm(forms.ModelForm): | ||||
|             extra_data = forms.CharField() | ||||
|  | ||||
| @@ -647,14 +644,14 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|             form = SongForm | ||||
|             fields = ['extra_data', 'title'] | ||||
|  | ||||
|         errors = FieldsOnFormOnlyAdmin.check(model=Song) | ||||
|         errors = FieldsOnFormOnlyAdmin(Song, AdminSite()).check() | ||||
|         self.assertEqual(errors, []) | ||||
|  | ||||
|     def test_check_sublists_for_duplicates(self): | ||||
|         class MyModelAdmin(admin.ModelAdmin): | ||||
|             fields = ['state', ['state']] | ||||
|  | ||||
|         errors = MyModelAdmin.check(model=Song) | ||||
|         errors = MyModelAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "The value of 'fields' contains duplicate field(s).", | ||||
| @@ -673,7 +670,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|                 }), | ||||
|             ] | ||||
|  | ||||
|         errors = MyModelAdmin.check(model=Song) | ||||
|         errors = MyModelAdmin(Song, AdminSite()).check() | ||||
|         expected = [ | ||||
|             checks.Error( | ||||
|                 "There are duplicate field(s) in 'fieldsets[0][1]'.", | ||||
| @@ -696,7 +693,7 @@ class SystemChecksTestCase(SimpleTestCase): | ||||
|         # if the value of 'list_filter' refers to a 'through__field'. | ||||
|         Book._meta.apps.ready = False | ||||
|         try: | ||||
|             errors = BookAdminWithListFilter.check(model=Book) | ||||
|             errors = BookAdminWithListFilter(Book, AdminSite()).check() | ||||
|             self.assertEqual(errors, []) | ||||
|         finally: | ||||
|             Book._meta.apps.ready = True | ||||
|   | ||||
		Reference in New Issue
	
	Block a user