mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Refs #33476 -- Reformatted code with Black.
This commit is contained in:
committed by
Mariusz Felisiak
parent
f68fa8b45d
commit
9c19aff7c7
@@ -17,7 +17,7 @@ class Song(models.Model):
|
||||
original_release = models.DateField(editable=False)
|
||||
|
||||
class Meta:
|
||||
ordering = ('title',)
|
||||
ordering = ("title",)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
@@ -41,7 +41,7 @@ class Book(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
subtitle = models.CharField(max_length=100)
|
||||
price = models.FloatField()
|
||||
authors = models.ManyToManyField(Author, through='AuthorsBooks')
|
||||
authors = models.ManyToManyField(Author, through="AuthorsBooks")
|
||||
|
||||
|
||||
class AuthorsBooks(models.Model):
|
||||
@@ -63,4 +63,4 @@ class Influence(models.Model):
|
||||
|
||||
content_type = models.ForeignKey(ContentType, models.CASCADE)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = GenericForeignKey('content_type', 'object_id')
|
||||
content_object = GenericForeignKey("content_type", "object_id")
|
||||
|
||||
@@ -9,9 +9,7 @@ from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.core import checks
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
|
||||
from .models import (
|
||||
Album, Author, Book, City, Influence, Song, State, TwoAlbumFKAndAnE,
|
||||
)
|
||||
from .models import Album, Author, Book, City, Influence, Song, State, TwoAlbumFKAndAnE
|
||||
|
||||
|
||||
class SongForm(forms.ModelForm):
|
||||
@@ -20,25 +18,29 @@ class SongForm(forms.ModelForm):
|
||||
|
||||
class ValidFields(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
fields = ['title']
|
||||
fields = ["title"]
|
||||
|
||||
|
||||
class ValidFormFieldsets(admin.ModelAdmin):
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
class ExtraFieldForm(SongForm):
|
||||
name = forms.CharField(max_length=50)
|
||||
|
||||
return ExtraFieldForm
|
||||
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': ('name',),
|
||||
}),
|
||||
(
|
||||
None,
|
||||
{
|
||||
"fields": ("name",),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class MyAdmin(admin.ModelAdmin):
|
||||
def check(self, **kwargs):
|
||||
return ['error!']
|
||||
return ["error!"]
|
||||
|
||||
|
||||
class AuthenticationMiddlewareSubclass(AuthenticationMiddleware):
|
||||
@@ -58,27 +60,26 @@ class SessionMiddlewareSubclass(SessionMiddleware):
|
||||
|
||||
|
||||
@override_settings(
|
||||
SILENCED_SYSTEM_CHECKS=['fields.W342'], # ForeignKey(unique=True)
|
||||
SILENCED_SYSTEM_CHECKS=["fields.W342"], # ForeignKey(unique=True)
|
||||
INSTALLED_APPS=[
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.messages',
|
||||
'admin_checks',
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.messages",
|
||||
"admin_checks",
|
||||
],
|
||||
)
|
||||
class SystemChecksTestCase(SimpleTestCase):
|
||||
|
||||
def test_checks_are_performed(self):
|
||||
admin.site.register(Song, MyAdmin)
|
||||
try:
|
||||
errors = checks.run_checks()
|
||||
expected = ['error!']
|
||||
expected = ["error!"]
|
||||
self.assertEqual(errors, expected)
|
||||
finally:
|
||||
admin.site.unregister(Song)
|
||||
|
||||
@override_settings(INSTALLED_APPS=['django.contrib.admin'])
|
||||
@override_settings(INSTALLED_APPS=["django.contrib.admin"])
|
||||
def test_apps_dependencies(self):
|
||||
errors = admin.checks.check_dependencies()
|
||||
expected = [
|
||||
@@ -90,36 +91,41 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"'django.contrib.auth' must be in INSTALLED_APPS in order "
|
||||
"to use the admin application.",
|
||||
id='admin.E405',
|
||||
id="admin.E405",
|
||||
),
|
||||
checks.Error(
|
||||
"'django.contrib.messages' must be in INSTALLED_APPS in order "
|
||||
"to use the admin application.",
|
||||
id='admin.E406',
|
||||
id="admin.E406",
|
||||
),
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
@override_settings(TEMPLATES=[])
|
||||
def test_no_template_engines(self):
|
||||
self.assertEqual(admin.checks.check_dependencies(), [
|
||||
checks.Error(
|
||||
"A 'django.template.backends.django.DjangoTemplates' "
|
||||
"instance must be configured in TEMPLATES in order to use "
|
||||
"the admin application.",
|
||||
id='admin.E403',
|
||||
)
|
||||
])
|
||||
self.assertEqual(
|
||||
admin.checks.check_dependencies(),
|
||||
[
|
||||
checks.Error(
|
||||
"A 'django.template.backends.django.DjangoTemplates' "
|
||||
"instance must be configured in TEMPLATES in order to use "
|
||||
"the admin application.",
|
||||
id="admin.E403",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [],
|
||||
},
|
||||
}],
|
||||
TEMPLATES=[
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [],
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
def test_context_processor_dependencies(self):
|
||||
expected = [
|
||||
@@ -127,20 +133,20 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"'django.contrib.auth.context_processors.auth' must be "
|
||||
"enabled in DjangoTemplates (TEMPLATES) if using the default "
|
||||
"auth backend in order to use the admin application.",
|
||||
id='admin.E402',
|
||||
id="admin.E402",
|
||||
),
|
||||
checks.Error(
|
||||
"'django.contrib.messages.context_processors.messages' must "
|
||||
"be enabled in DjangoTemplates (TEMPLATES) in order to use "
|
||||
"the admin application.",
|
||||
id='admin.E404',
|
||||
id="admin.E404",
|
||||
),
|
||||
checks.Warning(
|
||||
"'django.template.context_processors.request' must be enabled "
|
||||
"in DjangoTemplates (TEMPLATES) in order to use the admin "
|
||||
"navigation sidebar.",
|
||||
id='admin.W411',
|
||||
)
|
||||
id="admin.W411",
|
||||
),
|
||||
]
|
||||
self.assertEqual(admin.checks.check_dependencies(), expected)
|
||||
# The first error doesn't happen if
|
||||
@@ -150,45 +156,50 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
self.assertEqual(admin.checks.check_dependencies(), expected[1:])
|
||||
|
||||
@override_settings(
|
||||
AUTHENTICATION_BACKENDS=['admin_checks.tests.ModelBackendSubclass'],
|
||||
TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
}],
|
||||
AUTHENTICATION_BACKENDS=["admin_checks.tests.ModelBackendSubclass"],
|
||||
TEMPLATES=[
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
def test_context_processor_dependencies_model_backend_subclass(self):
|
||||
self.assertEqual(admin.checks.check_dependencies(), [
|
||||
checks.Error(
|
||||
"'django.contrib.auth.context_processors.auth' must be "
|
||||
"enabled in DjangoTemplates (TEMPLATES) if using the default "
|
||||
"auth backend in order to use the admin application.",
|
||||
id='admin.E402',
|
||||
),
|
||||
])
|
||||
self.assertEqual(
|
||||
admin.checks.check_dependencies(),
|
||||
[
|
||||
checks.Error(
|
||||
"'django.contrib.auth.context_processors.auth' must be "
|
||||
"enabled in DjangoTemplates (TEMPLATES) if using the default "
|
||||
"auth backend in order to use the admin application.",
|
||||
id="admin.E402",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
TEMPLATES=[
|
||||
{
|
||||
'BACKEND': 'django.template.backends.dummy.TemplateStrings',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
"BACKEND": "django.template.backends.dummy.TemplateStrings",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
},
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
@@ -204,12 +215,12 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"'django.contrib.auth.middleware.AuthenticationMiddleware' "
|
||||
"must be in MIDDLEWARE in order to use the admin application.",
|
||||
id='admin.E408',
|
||||
id="admin.E408",
|
||||
),
|
||||
checks.Error(
|
||||
"'django.contrib.messages.middleware.MessageMiddleware' "
|
||||
"must be in MIDDLEWARE in order to use the admin application.",
|
||||
id='admin.E409',
|
||||
id="admin.E409",
|
||||
),
|
||||
checks.Error(
|
||||
"'django.contrib.sessions.middleware.SessionMiddleware' "
|
||||
@@ -220,25 +231,29 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"before "
|
||||
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
|
||||
),
|
||||
id='admin.E410',
|
||||
id="admin.E410",
|
||||
),
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
@override_settings(MIDDLEWARE=[
|
||||
'admin_checks.tests.AuthenticationMiddlewareSubclass',
|
||||
'admin_checks.tests.MessageMiddlewareSubclass',
|
||||
'admin_checks.tests.SessionMiddlewareSubclass',
|
||||
])
|
||||
@override_settings(
|
||||
MIDDLEWARE=[
|
||||
"admin_checks.tests.AuthenticationMiddlewareSubclass",
|
||||
"admin_checks.tests.MessageMiddlewareSubclass",
|
||||
"admin_checks.tests.SessionMiddlewareSubclass",
|
||||
]
|
||||
)
|
||||
def test_middleware_subclasses(self):
|
||||
self.assertEqual(admin.checks.check_dependencies(), [])
|
||||
|
||||
@override_settings(MIDDLEWARE=[
|
||||
'django.contrib.does.not.Exist',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
])
|
||||
@override_settings(
|
||||
MIDDLEWARE=[
|
||||
"django.contrib.does.not.Exist",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
]
|
||||
)
|
||||
def test_admin_check_ignores_import_error_in_middleware(self):
|
||||
self.assertEqual(admin.checks.check_dependencies(), [])
|
||||
|
||||
@@ -250,7 +265,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
custom_site.register(Song, MyAdmin)
|
||||
try:
|
||||
errors = checks.run_checks()
|
||||
expected = ['error!']
|
||||
expected = ["error!"]
|
||||
self.assertEqual(errors, expected)
|
||||
finally:
|
||||
custom_site.unregister(Song)
|
||||
@@ -261,7 +276,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
errors = super().check(**kwargs)
|
||||
author_admin = self.admin_site._registry.get(Author)
|
||||
if author_admin is None:
|
||||
errors.append('AuthorAdmin missing!')
|
||||
errors.append("AuthorAdmin missing!")
|
||||
return errors
|
||||
|
||||
class MyAuthorAdmin(admin.ModelAdmin):
|
||||
@@ -285,35 +300,41 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"The value of 'list_editable[0]' refers to 'original_release', "
|
||||
"which is not contained in 'list_display'.",
|
||||
obj=SongAdmin,
|
||||
id='admin.E122',
|
||||
id="admin.E122",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
def test_list_editable_not_a_list_or_tuple(self):
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
list_editable = 'test'
|
||||
list_editable = "test"
|
||||
|
||||
self.assertEqual(SongAdmin(Song, AdminSite()).check(), [
|
||||
checks.Error(
|
||||
"The value of 'list_editable' must be a list or tuple.",
|
||||
obj=SongAdmin,
|
||||
id='admin.E120',
|
||||
)
|
||||
])
|
||||
self.assertEqual(
|
||||
SongAdmin(Song, AdminSite()).check(),
|
||||
[
|
||||
checks.Error(
|
||||
"The value of 'list_editable' must be a list or tuple.",
|
||||
obj=SongAdmin,
|
||||
id="admin.E120",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
def test_list_editable_missing_field(self):
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
list_editable = ('test',)
|
||||
list_editable = ("test",)
|
||||
|
||||
self.assertEqual(SongAdmin(Song, AdminSite()).check(), [
|
||||
checks.Error(
|
||||
"The value of 'list_editable[0]' refers to 'test', which is "
|
||||
"not a field of 'admin_checks.Song'.",
|
||||
obj=SongAdmin,
|
||||
id='admin.E121',
|
||||
)
|
||||
])
|
||||
self.assertEqual(
|
||||
SongAdmin(Song, AdminSite()).check(),
|
||||
[
|
||||
checks.Error(
|
||||
"The value of 'list_editable[0]' refers to 'test', which is "
|
||||
"not a field of 'admin_checks.Song'.",
|
||||
obj=SongAdmin,
|
||||
id="admin.E121",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
def test_readonly_and_editable(self):
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
@@ -321,17 +342,21 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
list_display = ["pk", "original_release"]
|
||||
list_editable = ["original_release"]
|
||||
fieldsets = [
|
||||
(None, {
|
||||
"fields": ["title", "original_release"],
|
||||
}),
|
||||
(
|
||||
None,
|
||||
{
|
||||
"fields": ["title", "original_release"],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
errors = SongAdmin(Song, AdminSite()).check()
|
||||
expected = [
|
||||
checks.Error(
|
||||
"The value of 'list_editable[0]' refers to 'original_release', "
|
||||
"which is not editable through the admin.",
|
||||
obj=SongAdmin,
|
||||
id='admin.E125',
|
||||
id="admin.E125",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -341,9 +366,12 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
list_display = ["pk", "title"]
|
||||
list_editable = ["title"]
|
||||
fieldsets = [
|
||||
(None, {
|
||||
"fields": ["title", "original_release"],
|
||||
}),
|
||||
(
|
||||
None,
|
||||
{
|
||||
"fields": ["title", "original_release"],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
errors = SongAdmin(Song, AdminSite()).check()
|
||||
@@ -368,13 +396,12 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"""
|
||||
The first fieldset's fields must be a list/tuple.
|
||||
"""
|
||||
|
||||
class NotATupleAdmin(admin.ModelAdmin):
|
||||
list_display = ["pk", "title"]
|
||||
list_editable = ["title"]
|
||||
fieldsets = [
|
||||
(None, {
|
||||
"fields": "title" # not a tuple
|
||||
}),
|
||||
(None, {"fields": "title"}), # not a tuple
|
||||
]
|
||||
|
||||
errors = NotATupleAdmin(Song, AdminSite()).check()
|
||||
@@ -382,7 +409,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"The value of 'fieldsets[0][1]['fields']' must be a list or tuple.",
|
||||
obj=NotATupleAdmin,
|
||||
id='admin.E008',
|
||||
id="admin.E008",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -391,14 +418,11 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"""
|
||||
The second fieldset's fields must be a list/tuple.
|
||||
"""
|
||||
|
||||
class NotATupleAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {
|
||||
"fields": ("title",)
|
||||
}),
|
||||
('foo', {
|
||||
"fields": "author" # not a tuple
|
||||
}),
|
||||
(None, {"fields": ("title",)}),
|
||||
("foo", {"fields": "author"}), # not a tuple
|
||||
]
|
||||
|
||||
errors = NotATupleAdmin(Song, AdminSite()).check()
|
||||
@@ -406,7 +430,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"The value of 'fieldsets[1][1]['fields']' must be a list or tuple.",
|
||||
obj=NotATupleAdmin,
|
||||
id='admin.E008',
|
||||
id="admin.E008",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -415,29 +439,30 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"""
|
||||
Tests for basic system checks of 'exclude' option values (#12689)
|
||||
"""
|
||||
|
||||
class ExcludedFields1(admin.ModelAdmin):
|
||||
exclude = 'foo'
|
||||
exclude = "foo"
|
||||
|
||||
errors = ExcludedFields1(Book, AdminSite()).check()
|
||||
expected = [
|
||||
checks.Error(
|
||||
"The value of 'exclude' must be a list or tuple.",
|
||||
obj=ExcludedFields1,
|
||||
id='admin.E014',
|
||||
id="admin.E014",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
def test_exclude_duplicate_values(self):
|
||||
class ExcludedFields2(admin.ModelAdmin):
|
||||
exclude = ('name', 'name')
|
||||
exclude = ("name", "name")
|
||||
|
||||
errors = ExcludedFields2(Book, AdminSite()).check()
|
||||
expected = [
|
||||
checks.Error(
|
||||
"The value of 'exclude' contains duplicate field(s).",
|
||||
obj=ExcludedFields2,
|
||||
id='admin.E015',
|
||||
id="admin.E015",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -445,7 +470,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
def test_exclude_in_inline(self):
|
||||
class ExcludedFieldsInline(admin.TabularInline):
|
||||
model = Song
|
||||
exclude = 'foo'
|
||||
exclude = "foo"
|
||||
|
||||
class ExcludedFieldsAlbumAdmin(admin.ModelAdmin):
|
||||
model = Album
|
||||
@@ -456,7 +481,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"The value of 'exclude' must be a list or tuple.",
|
||||
obj=ExcludedFieldsInline,
|
||||
id='admin.E014',
|
||||
id="admin.E014",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -466,9 +491,10 @@ 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']
|
||||
exclude = ["album"]
|
||||
|
||||
class AlbumAdmin(admin.ModelAdmin):
|
||||
model = Album
|
||||
@@ -480,7 +506,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"Cannot exclude the field 'album', because it is the foreign key "
|
||||
"to the parent model 'admin_checks.Album'.",
|
||||
obj=SongInline,
|
||||
id='admin.E201',
|
||||
id="admin.E201",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -490,6 +516,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
Regression test for #22034 - check that generic inlines don't look for
|
||||
normal ForeignKey relations.
|
||||
"""
|
||||
|
||||
class InfluenceInline(GenericStackedInline):
|
||||
model = Influence
|
||||
|
||||
@@ -504,6 +531,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
A model without a GenericForeignKey raises problems if it's included
|
||||
in a GenericInlineModelAdmin definition.
|
||||
"""
|
||||
|
||||
class BookInline(GenericStackedInline):
|
||||
model = Book
|
||||
|
||||
@@ -515,7 +543,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"'admin_checks.Book' has no GenericForeignKey.",
|
||||
obj=BookInline,
|
||||
id='admin.E301',
|
||||
id="admin.E301",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -525,9 +553,10 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
A GenericInlineModelAdmin errors if the ct_field points to a
|
||||
nonexistent field.
|
||||
"""
|
||||
|
||||
class InfluenceInline(GenericStackedInline):
|
||||
model = Influence
|
||||
ct_field = 'nonexistent'
|
||||
ct_field = "nonexistent"
|
||||
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
inlines = [InfluenceInline]
|
||||
@@ -537,7 +566,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"'ct_field' references 'nonexistent', which is not a field on 'admin_checks.Influence'.",
|
||||
obj=InfluenceInline,
|
||||
id='admin.E302',
|
||||
id="admin.E302",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -547,9 +576,10 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
A GenericInlineModelAdmin errors if the ct_fk_field points to a
|
||||
nonexistent field.
|
||||
"""
|
||||
|
||||
class InfluenceInline(GenericStackedInline):
|
||||
model = Influence
|
||||
ct_fk_field = 'nonexistent'
|
||||
ct_fk_field = "nonexistent"
|
||||
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
inlines = [InfluenceInline]
|
||||
@@ -559,7 +589,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"'ct_fk_field' references 'nonexistent', which is not a field on 'admin_checks.Influence'.",
|
||||
obj=InfluenceInline,
|
||||
id='admin.E303',
|
||||
id="admin.E303",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -569,9 +599,10 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
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'
|
||||
ct_field = "name"
|
||||
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
inlines = [InfluenceInline]
|
||||
@@ -582,7 +613,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"'admin_checks.Influence' has no GenericForeignKey using "
|
||||
"content type field 'name' and object ID field 'object_id'.",
|
||||
obj=InfluenceInline,
|
||||
id='admin.E304',
|
||||
id="admin.E304",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -592,9 +623,10 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
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'
|
||||
ct_fk_field = "name"
|
||||
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
inlines = [InfluenceInline]
|
||||
@@ -605,14 +637,14 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"'admin_checks.Influence' has no GenericForeignKey using "
|
||||
"content type field 'content_type' and object ID field 'name'.",
|
||||
obj=InfluenceInline,
|
||||
id='admin.E304',
|
||||
id="admin.E304",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
def test_app_label_in_admin_checks(self):
|
||||
class RawIdNonexistentAdmin(admin.ModelAdmin):
|
||||
raw_id_fields = ('nonexistent',)
|
||||
raw_id_fields = ("nonexistent",)
|
||||
|
||||
errors = RawIdNonexistentAdmin(Album, AdminSite()).check()
|
||||
expected = [
|
||||
@@ -620,7 +652,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"The value of 'raw_id_fields[0]' refers to 'nonexistent', "
|
||||
"which is not a field of 'admin_checks.Album'.",
|
||||
obj=RawIdNonexistentAdmin,
|
||||
id='admin.E002',
|
||||
id="admin.E002",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -631,6 +663,7 @@ 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",)
|
||||
@@ -656,7 +689,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"to 'admin_checks.Album'. You must specify a 'fk_name' "
|
||||
"attribute.",
|
||||
obj=TwoAlbumFKAndAnEInline,
|
||||
id='admin.E202',
|
||||
id="admin.E202",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -719,9 +752,11 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
|
||||
def __getattr__(self, item):
|
||||
if item == "dynamic_method":
|
||||
|
||||
@admin.display
|
||||
def method(obj):
|
||||
pass
|
||||
|
||||
return method
|
||||
raise AttributeError
|
||||
|
||||
@@ -745,7 +780,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"The value of 'readonly_fields[1]' is not a callable, an attribute "
|
||||
"of 'SongAdmin', or an attribute of 'admin_checks.Song'.",
|
||||
obj=SongAdmin,
|
||||
id='admin.E035',
|
||||
id="admin.E035",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -753,7 +788,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
def test_nonexistent_field_on_inline(self):
|
||||
class CityInline(admin.TabularInline):
|
||||
model = City
|
||||
readonly_fields = ['i_dont_exist'] # Missing attribute
|
||||
readonly_fields = ["i_dont_exist"] # Missing attribute
|
||||
|
||||
errors = CityInline(State, AdminSite()).check()
|
||||
expected = [
|
||||
@@ -761,22 +796,25 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"The value of 'readonly_fields[0]' is not a callable, an attribute "
|
||||
"of 'CityInline', or an attribute of 'admin_checks.City'.",
|
||||
obj=CityInline,
|
||||
id='admin.E035',
|
||||
id="admin.E035",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
def test_readonly_fields_not_list_or_tuple(self):
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
readonly_fields = 'test'
|
||||
readonly_fields = "test"
|
||||
|
||||
self.assertEqual(SongAdmin(Song, AdminSite()).check(), [
|
||||
checks.Error(
|
||||
"The value of 'readonly_fields' must be a list or tuple.",
|
||||
obj=SongAdmin,
|
||||
id='admin.E034',
|
||||
)
|
||||
])
|
||||
self.assertEqual(
|
||||
SongAdmin(Song, AdminSite()).check(),
|
||||
[
|
||||
checks.Error(
|
||||
"The value of 'readonly_fields' must be a list or tuple.",
|
||||
obj=SongAdmin,
|
||||
id="admin.E034",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
def test_extra(self):
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
@@ -802,8 +840,9 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
specifies the 'through' option is included in the 'fields' or the 'fieldsets'
|
||||
ModelAdmin options.
|
||||
"""
|
||||
|
||||
class BookAdmin(admin.ModelAdmin):
|
||||
fields = ['authors']
|
||||
fields = ["authors"]
|
||||
|
||||
errors = BookAdmin(Book, AdminSite()).check()
|
||||
expected = [
|
||||
@@ -811,7 +850,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"The value of 'fields' cannot include the ManyToManyField 'authors', "
|
||||
"because that field manually specifies a relationship model.",
|
||||
obj=BookAdmin,
|
||||
id='admin.E013',
|
||||
id="admin.E013",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -819,8 +858,8 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
def test_cannot_include_through(self):
|
||||
class FieldsetBookAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
('Header 1', {'fields': ('name',)}),
|
||||
('Header 2', {'fields': ('authors',)}),
|
||||
("Header 1", {"fields": ("name",)}),
|
||||
("Header 2", {"fields": ("authors",)}),
|
||||
)
|
||||
|
||||
errors = FieldsetBookAdmin(Book, AdminSite()).check()
|
||||
@@ -829,23 +868,21 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
"The value of 'fieldsets[1][1][\"fields\"]' cannot include the ManyToManyField "
|
||||
"'authors', because that field manually specifies a relationship model.",
|
||||
obj=FieldsetBookAdmin,
|
||||
id='admin.E013',
|
||||
id="admin.E013",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
|
||||
def test_nested_fields(self):
|
||||
class NestedFieldsAdmin(admin.ModelAdmin):
|
||||
fields = ('price', ('name', 'subtitle'))
|
||||
fields = ("price", ("name", "subtitle"))
|
||||
|
||||
errors = NestedFieldsAdmin(Book, AdminSite()).check()
|
||||
self.assertEqual(errors, [])
|
||||
|
||||
def test_nested_fieldsets(self):
|
||||
class NestedFieldsetAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
('Main', {'fields': ('price', ('name', 'subtitle'))}),
|
||||
)
|
||||
fieldsets = (("Main", {"fields": ("price", ("name", "subtitle"))}),)
|
||||
|
||||
errors = NestedFieldsetAdmin(Book, AdminSite()).check()
|
||||
self.assertEqual(errors, [])
|
||||
@@ -856,6 +893,7 @@ 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
|
||||
|
||||
@@ -870,12 +908,13 @@ 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()
|
||||
|
||||
class FieldsOnFormOnlyAdmin(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
fields = ['title', 'extra_data']
|
||||
fields = ["title", "extra_data"]
|
||||
|
||||
errors = FieldsOnFormOnlyAdmin(Song, AdminSite()).check()
|
||||
self.assertEqual(errors, [])
|
||||
@@ -885,30 +924,31 @@ 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()
|
||||
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
class FieldsOnFormOnlyAdmin(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
fields = ['extra_data', 'title']
|
||||
fields = ["extra_data", "title"]
|
||||
|
||||
errors = FieldsOnFormOnlyAdmin(Song, AdminSite()).check()
|
||||
self.assertEqual(errors, [])
|
||||
|
||||
def test_check_sublists_for_duplicates(self):
|
||||
class MyModelAdmin(admin.ModelAdmin):
|
||||
fields = ['state', ['state']]
|
||||
fields = ["state", ["state"]]
|
||||
|
||||
errors = MyModelAdmin(Song, AdminSite()).check()
|
||||
expected = [
|
||||
checks.Error(
|
||||
"The value of 'fields' contains duplicate field(s).",
|
||||
obj=MyModelAdmin,
|
||||
id='admin.E006'
|
||||
id="admin.E006",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -916,9 +956,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
def test_check_fieldset_sublists_for_duplicates(self):
|
||||
class MyModelAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {
|
||||
'fields': ['title', 'album', ('title', 'album')]
|
||||
}),
|
||||
(None, {"fields": ["title", "album", ("title", "album")]}),
|
||||
]
|
||||
|
||||
errors = MyModelAdmin(Song, AdminSite()).check()
|
||||
@@ -926,7 +964,7 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
checks.Error(
|
||||
"There are duplicate field(s) in 'fieldsets[0][1]'.",
|
||||
obj=MyModelAdmin,
|
||||
id='admin.E012'
|
||||
id="admin.E012",
|
||||
)
|
||||
]
|
||||
self.assertEqual(errors, expected)
|
||||
@@ -936,8 +974,9 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||
Ensure list_filter can access reverse fields even when the app registry
|
||||
is not ready; refs #24146.
|
||||
"""
|
||||
|
||||
class BookAdminWithListFilter(admin.ModelAdmin):
|
||||
list_filter = ['authorsbooks__featured']
|
||||
list_filter = ["authorsbooks__featured"]
|
||||
|
||||
# Temporarily pretending apps are not ready yet. This issue can happen
|
||||
# if the value of 'list_filter' refers to a 'through__field'.
|
||||
|
||||
Reference in New Issue
Block a user