summaryrefslogtreecommitdiff
path: root/tests/admin_changelist
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/admin_changelist
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
downloaddjango-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/admin_changelist')
-rw-r--r--tests/admin_changelist/admin.py92
-rw-r--r--tests/admin_changelist/models.py12
-rw-r--r--tests/admin_changelist/test_date_hierarchy.py71
-rw-r--r--tests/admin_changelist/tests.py1200
-rw-r--r--tests/admin_changelist/urls.py2
5 files changed, 757 insertions, 620 deletions
diff --git a/tests/admin_changelist/admin.py b/tests/admin_changelist/admin.py
index 929539ea88..67187f5b79 100644
--- a/tests/admin_changelist/admin.py
+++ b/tests/admin_changelist/admin.py
@@ -12,12 +12,14 @@ site.register(User, UserAdmin)
class CustomPaginator(Paginator):
def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True):
- super().__init__(queryset, 5, orphans=2, allow_empty_first_page=allow_empty_first_page)
+ super().__init__(
+ queryset, 5, orphans=2, allow_empty_first_page=allow_empty_first_page
+ )
class EventAdmin(admin.ModelAdmin):
- date_hierarchy = 'date'
- list_display = ['event_date_func']
+ date_hierarchy = "date"
+ list_display = ["event_date_func"]
@admin.display
def event_date_func(self, event):
@@ -31,21 +33,21 @@ site.register(Event, EventAdmin)
class ParentAdmin(admin.ModelAdmin):
- list_filter = ['child__name']
- search_fields = ['child__name']
- list_select_related = ['child']
+ list_filter = ["child__name"]
+ search_fields = ["child__name"]
+ list_select_related = ["child"]
class ParentAdminTwoSearchFields(admin.ModelAdmin):
- list_filter = ['child__name']
- search_fields = ['child__name', 'child__age']
- list_select_related = ['child']
+ list_filter = ["child__name"]
+ search_fields = ["child__name", "child__age"]
+ list_select_related = ["child"]
class ChildAdmin(admin.ModelAdmin):
- list_display = ['name', 'parent']
+ list_display = ["name", "parent"]
list_per_page = 10
- list_filter = ['parent', 'age']
+ list_filter = ["parent", "age"]
def get_queryset(self, request):
return super().get_queryset(request).select_related("parent")
@@ -56,32 +58,32 @@ class CustomPaginationAdmin(ChildAdmin):
class FilteredChildAdmin(admin.ModelAdmin):
- list_display = ['name', 'parent']
+ list_display = ["name", "parent"]
list_per_page = 10
def get_queryset(self, request):
- return super().get_queryset(request).filter(name__contains='filtered')
+ return super().get_queryset(request).filter(name__contains="filtered")
class BandAdmin(admin.ModelAdmin):
- list_filter = ['genres']
+ list_filter = ["genres"]
class NrOfMembersFilter(admin.SimpleListFilter):
- title = 'number of members'
- parameter_name = 'nr_of_members_partition'
+ title = "number of members"
+ parameter_name = "nr_of_members_partition"
def lookups(self, request, model_admin):
return [
- ('5', '0 - 5'),
- ('more', 'more than 5'),
+ ("5", "0 - 5"),
+ ("more", "more than 5"),
]
def queryset(self, request, queryset):
value = self.value()
- if value == '5':
+ if value == "5":
return queryset.filter(nr_of_members__lte=5)
- if value == 'more':
+ if value == "more":
return queryset.filter(nr_of_members__gt=5)
@@ -93,44 +95,44 @@ site.register(Band, BandCallableFilterAdmin)
class GroupAdmin(admin.ModelAdmin):
- list_filter = ['members']
+ list_filter = ["members"]
class ConcertAdmin(admin.ModelAdmin):
- list_filter = ['group__members']
- search_fields = ['group__members__name']
+ list_filter = ["group__members"]
+ search_fields = ["group__members__name"]
class QuartetAdmin(admin.ModelAdmin):
- list_filter = ['members']
+ list_filter = ["members"]
class ChordsBandAdmin(admin.ModelAdmin):
- list_filter = ['members']
+ list_filter = ["members"]
class InvitationAdmin(admin.ModelAdmin):
- list_display = ('band', 'player')
- list_select_related = ('player',)
+ list_display = ("band", "player")
+ list_select_related = ("player",)
class DynamicListDisplayChildAdmin(admin.ModelAdmin):
- list_display = ('parent', 'name', 'age')
+ list_display = ("parent", "name", "age")
def get_list_display(self, request):
my_list_display = super().get_list_display(request)
- if request.user.username == 'noparents':
+ if request.user.username == "noparents":
my_list_display = list(my_list_display)
- my_list_display.remove('parent')
+ my_list_display.remove("parent")
return my_list_display
class DynamicListDisplayLinksChildAdmin(admin.ModelAdmin):
- list_display = ('parent', 'name', 'age')
- list_display_links = ['parent', 'name']
+ list_display = ("parent", "name", "age")
+ list_display_links = ["parent", "name"]
def get_list_display_links(self, request, list_display):
- return ['age']
+ return ["age"]
site.register(Child, DynamicListDisplayChildAdmin)
@@ -138,8 +140,8 @@ site.register(Child, DynamicListDisplayChildAdmin)
class NoListDisplayLinksParentAdmin(admin.ModelAdmin):
list_display_links = None
- list_display = ['name']
- list_editable = ['name']
+ list_display = ["name"]
+ list_editable = ["name"]
actions_on_bottom = True
@@ -148,8 +150,8 @@ site.register(Parent, NoListDisplayLinksParentAdmin)
class SwallowAdmin(admin.ModelAdmin):
actions = None # prevent ['action_checkbox'] + list(list_display)
- list_display = ('origin', 'load', 'speed', 'swallowonetoone')
- list_editable = ['load', 'speed']
+ list_display = ("origin", "load", "speed", "swallowonetoone")
+ list_editable = ["load", "speed"]
list_per_page = 3
@@ -157,29 +159,29 @@ site.register(Swallow, SwallowAdmin)
class DynamicListFilterChildAdmin(admin.ModelAdmin):
- list_filter = ('parent', 'name', 'age')
+ list_filter = ("parent", "name", "age")
def get_list_filter(self, request):
my_list_filter = super().get_list_filter(request)
- if request.user.username == 'noparents':
+ if request.user.username == "noparents":
my_list_filter = list(my_list_filter)
- my_list_filter.remove('parent')
+ my_list_filter.remove("parent")
return my_list_filter
class DynamicSearchFieldsChildAdmin(admin.ModelAdmin):
- search_fields = ('name',)
+ search_fields = ("name",)
def get_search_fields(self, request):
search_fields = super().get_search_fields(request)
- search_fields += ('age',)
+ search_fields += ("age",)
return search_fields
class EmptyValueChildAdmin(admin.ModelAdmin):
- empty_value_display = '-empty-'
- list_display = ('name', 'age_display', 'age')
+ empty_value_display = "-empty-"
+ list_display = ("name", "age_display", "age")
- @admin.display(empty_value='&dagger;')
+ @admin.display(empty_value="&dagger;")
def age_display(self, obj):
return obj.age
diff --git a/tests/admin_changelist/models.py b/tests/admin_changelist/models.py
index 81d7fdfb3a..180c38428a 100644
--- a/tests/admin_changelist/models.py
+++ b/tests/admin_changelist/models.py
@@ -38,7 +38,7 @@ class Musician(models.Model):
class Group(models.Model):
name = models.CharField(max_length=30)
- members = models.ManyToManyField(Musician, through='Membership')
+ members = models.ManyToManyField(Musician, through="Membership")
def __str__(self):
return self.name
@@ -65,7 +65,7 @@ class ChordsMusician(Musician):
class ChordsBand(models.Model):
name = models.CharField(max_length=30)
- members = models.ManyToManyField(ChordsMusician, through='Invitation')
+ members = models.ManyToManyField(ChordsMusician, through="Invitation")
class Invitation(models.Model):
@@ -81,7 +81,7 @@ class Swallow(models.Model):
speed = models.FloatField()
class Meta:
- ordering = ('speed', 'load')
+ ordering = ("speed", "load")
class SwallowOneToOne(models.Model):
@@ -93,12 +93,13 @@ class UnorderedObject(models.Model):
Model without any defined `Meta.ordering`.
Refs #17198.
"""
+
bool = models.BooleanField(default=True)
class OrderedObjectManager(models.Manager):
def get_queryset(self):
- return super().get_queryset().order_by('number')
+ return super().get_queryset().order_by("number")
class OrderedObject(models.Model):
@@ -106,9 +107,10 @@ class OrderedObject(models.Model):
Model with Manager that defines a default order.
Refs #17198.
"""
+
name = models.CharField(max_length=255)
bool = models.BooleanField(default=True)
- number = models.IntegerField(default=0, db_column='number_val')
+ number = models.IntegerField(default=0, db_column="number_val")
objects = OrderedObjectManager()
diff --git a/tests/admin_changelist/test_date_hierarchy.py b/tests/admin_changelist/test_date_hierarchy.py
index a321650b32..a8c10f7cd8 100644
--- a/tests/admin_changelist/test_date_hierarchy.py
+++ b/tests/admin_changelist/test_date_hierarchy.py
@@ -5,7 +5,8 @@ from django.contrib.auth.models import User
from django.test import RequestFactory, TestCase
from django.utils.timezone import make_aware
-from .admin import EventAdmin, site as custom_site
+from .admin import EventAdmin
+from .admin import site as custom_site
from .models import Event
@@ -14,34 +15,48 @@ class DateHierarchyTests(TestCase):
@classmethod
def setUpTestData(cls):
- cls.superuser = User.objects.create_superuser(username='super', email='a@b.com', password='xxx')
+ cls.superuser = User.objects.create_superuser(
+ username="super", email="a@b.com", password="xxx"
+ )
def assertDateParams(self, query, expected_from_date, expected_to_date):
- query = {'date__%s' % field: val for field, val in query.items()}
- request = self.factory.get('/', query)
+ query = {"date__%s" % field: val for field, val in query.items()}
+ request = self.factory.get("/", query)
request.user = self.superuser
changelist = EventAdmin(Event, custom_site).get_changelist_instance(request)
_, _, lookup_params, *_ = changelist.get_filters(request)
- self.assertEqual(lookup_params['date__gte'], expected_from_date)
- self.assertEqual(lookup_params['date__lt'], expected_to_date)
+ self.assertEqual(lookup_params["date__gte"], expected_from_date)
+ self.assertEqual(lookup_params["date__lt"], expected_to_date)
def test_bounded_params(self):
tests = (
- ({'year': 2017}, datetime(2017, 1, 1), datetime(2018, 1, 1)),
- ({'year': 2017, 'month': 2}, datetime(2017, 2, 1), datetime(2017, 3, 1)),
- ({'year': 2017, 'month': 12}, datetime(2017, 12, 1), datetime(2018, 1, 1)),
- ({'year': 2017, 'month': 12, 'day': 15}, datetime(2017, 12, 15), datetime(2017, 12, 16)),
- ({'year': 2017, 'month': 12, 'day': 31}, datetime(2017, 12, 31), datetime(2018, 1, 1)),
- ({'year': 2017, 'month': 2, 'day': 28}, datetime(2017, 2, 28), datetime(2017, 3, 1)),
+ ({"year": 2017}, datetime(2017, 1, 1), datetime(2018, 1, 1)),
+ ({"year": 2017, "month": 2}, datetime(2017, 2, 1), datetime(2017, 3, 1)),
+ ({"year": 2017, "month": 12}, datetime(2017, 12, 1), datetime(2018, 1, 1)),
+ (
+ {"year": 2017, "month": 12, "day": 15},
+ datetime(2017, 12, 15),
+ datetime(2017, 12, 16),
+ ),
+ (
+ {"year": 2017, "month": 12, "day": 31},
+ datetime(2017, 12, 31),
+ datetime(2018, 1, 1),
+ ),
+ (
+ {"year": 2017, "month": 2, "day": 28},
+ datetime(2017, 2, 28),
+ datetime(2017, 3, 1),
+ ),
)
for query, expected_from_date, expected_to_date in tests:
with self.subTest(query=query):
self.assertDateParams(query, expected_from_date, expected_to_date)
def test_bounded_params_with_time_zone(self):
- with self.settings(USE_TZ=True, TIME_ZONE='Asia/Jerusalem'):
+ with self.settings(USE_TZ=True, TIME_ZONE="Asia/Jerusalem"):
self.assertDateParams(
- {'year': 2017, 'month': 2, 'day': 28},
+ {"year": 2017, "month": 2, "day": 28},
make_aware(datetime(2017, 2, 28)),
make_aware(datetime(2017, 3, 1)),
)
@@ -49,31 +64,33 @@ class DateHierarchyTests(TestCase):
def test_bounded_params_with_dst_time_zone(self):
tests = [
# Northern hemisphere.
- ('Asia/Jerusalem', 3),
- ('Asia/Jerusalem', 10),
+ ("Asia/Jerusalem", 3),
+ ("Asia/Jerusalem", 10),
# Southern hemisphere.
- ('Pacific/Chatham', 4),
- ('Pacific/Chatham', 9),
+ ("Pacific/Chatham", 4),
+ ("Pacific/Chatham", 9),
]
for time_zone, month in tests:
with self.subTest(time_zone=time_zone, month=month):
with self.settings(USE_TZ=True, TIME_ZONE=time_zone):
self.assertDateParams(
- {'year': 2019, 'month': month},
+ {"year": 2019, "month": month},
make_aware(datetime(2019, month, 1)),
make_aware(datetime(2019, month + 1, 1)),
)
def test_invalid_params(self):
tests = (
- {'year': 'x'},
- {'year': 2017, 'month': 'x'},
- {'year': 2017, 'month': 12, 'day': 'x'},
- {'year': 2017, 'month': 13},
- {'year': 2017, 'month': 12, 'day': 32},
- {'year': 2017, 'month': 0},
- {'year': 2017, 'month': 12, 'day': 0},
+ {"year": "x"},
+ {"year": 2017, "month": "x"},
+ {"year": 2017, "month": 12, "day": "x"},
+ {"year": 2017, "month": 13},
+ {"year": 2017, "month": 12, "day": 32},
+ {"year": 2017, "month": 0},
+ {"year": 2017, "month": 12, "day": 0},
)
for invalid_query in tests:
- with self.subTest(query=invalid_query), self.assertRaises(IncorrectLookupParameters):
+ with self.subTest(query=invalid_query), self.assertRaises(
+ IncorrectLookupParameters
+ ):
self.assertDateParams(invalid_query, None, None)
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index 86fcab531a..7d6deced7e 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -6,7 +6,12 @@ from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.admin.templatetags.admin_list import pagination
from django.contrib.admin.tests import AdminSeleniumTestCase
from django.contrib.admin.views.main import (
- ALL_VAR, IS_POPUP_VAR, ORDER_VAR, PAGE_VAR, SEARCH_VAR, TO_FIELD_VAR,
+ ALL_VAR,
+ IS_POPUP_VAR,
+ ORDER_VAR,
+ PAGE_VAR,
+ SEARCH_VAR,
+ TO_FIELD_VAR,
)
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
@@ -18,36 +23,64 @@ from django.db.models.lookups import Contains, Exact
from django.template import Context, Template, TemplateSyntaxError
from django.test import TestCase, override_settings
from django.test.client import RequestFactory
-from django.test.utils import (
- CaptureQueriesContext, isolate_apps, register_lookup,
-)
+from django.test.utils import CaptureQueriesContext, isolate_apps, register_lookup
from django.urls import reverse
from django.utils import formats
from .admin import (
- BandAdmin, ChildAdmin, ChordsBandAdmin, ConcertAdmin,
- CustomPaginationAdmin, CustomPaginator, DynamicListDisplayChildAdmin,
- DynamicListDisplayLinksChildAdmin, DynamicListFilterChildAdmin,
- DynamicSearchFieldsChildAdmin, EmptyValueChildAdmin, EventAdmin,
- FilteredChildAdmin, GroupAdmin, InvitationAdmin,
- NoListDisplayLinksParentAdmin, ParentAdmin, ParentAdminTwoSearchFields,
- QuartetAdmin, SwallowAdmin, site as custom_site,
+ BandAdmin,
+ ChildAdmin,
+ ChordsBandAdmin,
+ ConcertAdmin,
+ CustomPaginationAdmin,
+ CustomPaginator,
+ DynamicListDisplayChildAdmin,
+ DynamicListDisplayLinksChildAdmin,
+ DynamicListFilterChildAdmin,
+ DynamicSearchFieldsChildAdmin,
+ EmptyValueChildAdmin,
+ EventAdmin,
+ FilteredChildAdmin,
+ GroupAdmin,
+ InvitationAdmin,
+ NoListDisplayLinksParentAdmin,
+ ParentAdmin,
+ ParentAdminTwoSearchFields,
+ QuartetAdmin,
+ SwallowAdmin,
)
+from .admin import site as custom_site
from .models import (
- Band, CharPK, Child, ChordsBand, ChordsMusician, Concert, CustomIdUser,
- Event, Genre, Group, Invitation, Membership, Musician, OrderedObject,
- Parent, Quartet, Swallow, SwallowOneToOne, UnorderedObject,
+ Band,
+ CharPK,
+ Child,
+ ChordsBand,
+ ChordsMusician,
+ Concert,
+ CustomIdUser,
+ Event,
+ Genre,
+ Group,
+ Invitation,
+ Membership,
+ Musician,
+ OrderedObject,
+ Parent,
+ Quartet,
+ Swallow,
+ SwallowOneToOne,
+ UnorderedObject,
)
def build_tbody_html(pk, href, extra_fields):
return (
- '<tbody><tr>'
+ "<tbody><tr>"
'<td class="action-checkbox">'
'<input type="checkbox" name="_selected_action" value="{}" '
'class="action-select"></td>'
'<th class="field-name"><a href="{}">name</a></th>'
- '{}</tr></tbody>'
+ "{}</tr></tbody>"
).format(pk, href, extra_fields)
@@ -57,10 +90,14 @@ class ChangeListTests(TestCase):
@classmethod
def setUpTestData(cls):
- cls.superuser = User.objects.create_superuser(username='super', email='a@b.com', password='xxx')
+ cls.superuser = User.objects.create_superuser(
+ username="super", email="a@b.com", password="xxx"
+ )
def _create_superuser(self, username):
- return User.objects.create_superuser(username=username, email='a@b.com', password='xxx')
+ return User.objects.create_superuser(
+ username=username, email="a@b.com", password="xxx"
+ )
def _mocked_authenticated_request(self, url, user):
request = self.factory.get(url)
@@ -69,36 +106,36 @@ class ChangeListTests(TestCase):
def test_repr(self):
m = ChildAdmin(Child, custom_site)
- request = self.factory.get('/child/')
+ request = self.factory.get("/child/")
request.user = self.superuser
cl = m.get_changelist_instance(request)
- self.assertEqual(repr(cl), '<ChangeList: model=Child model_admin=ChildAdmin>')
+ self.assertEqual(repr(cl), "<ChangeList: model=Child model_admin=ChildAdmin>")
def test_specified_ordering_by_f_expression(self):
class OrderedByFBandAdmin(admin.ModelAdmin):
- list_display = ['name', 'genres', 'nr_of_members']
+ list_display = ["name", "genres", "nr_of_members"]
ordering = (
- F('nr_of_members').desc(nulls_last=True),
- Upper(F('name')).asc(),
- F('genres').asc(),
+ F("nr_of_members").desc(nulls_last=True),
+ Upper(F("name")).asc(),
+ F("genres").asc(),
)
m = OrderedByFBandAdmin(Band, custom_site)
- request = self.factory.get('/band/')
+ request = self.factory.get("/band/")
request.user = self.superuser
cl = m.get_changelist_instance(request)
- self.assertEqual(cl.get_ordering_field_columns(), {3: 'desc', 2: 'asc'})
+ self.assertEqual(cl.get_ordering_field_columns(), {3: "desc", 2: "asc"})
def test_specified_ordering_by_f_expression_without_asc_desc(self):
class OrderedByFBandAdmin(admin.ModelAdmin):
- list_display = ['name', 'genres', 'nr_of_members']
- ordering = (F('nr_of_members'), Upper('name'), F('genres'))
+ list_display = ["name", "genres", "nr_of_members"]
+ ordering = (F("nr_of_members"), Upper("name"), F("genres"))
m = OrderedByFBandAdmin(Band, custom_site)
- request = self.factory.get('/band/')
+ request = self.factory.get("/band/")
request.user = self.superuser
cl = m.get_changelist_instance(request)
- self.assertEqual(cl.get_ordering_field_columns(), {3: 'asc', 2: 'asc'})
+ self.assertEqual(cl.get_ordering_field_columns(), {3: "asc", 2: "asc"})
def test_select_related_preserved(self):
"""
@@ -106,85 +143,85 @@ class ChangeListTests(TestCase):
overwrite a custom select_related provided by ModelAdmin.get_queryset().
"""
m = ChildAdmin(Child, custom_site)
- request = self.factory.get('/child/')
+ request = self.factory.get("/child/")
request.user = self.superuser
cl = m.get_changelist_instance(request)
- self.assertEqual(cl.queryset.query.select_related, {'parent': {}})
+ self.assertEqual(cl.queryset.query.select_related, {"parent": {}})
def test_select_related_preserved_when_multi_valued_in_search_fields(self):
- parent = Parent.objects.create(name='Mary')
- Child.objects.create(parent=parent, name='Danielle')
- Child.objects.create(parent=parent, name='Daniel')
+ parent = Parent.objects.create(name="Mary")
+ Child.objects.create(parent=parent, name="Danielle")
+ Child.objects.create(parent=parent, name="Daniel")
m = ParentAdmin(Parent, custom_site)
- request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel'})
+ request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertEqual(cl.queryset.count(), 1)
# select_related is preserved.
- self.assertEqual(cl.queryset.query.select_related, {'child': {}})
+ self.assertEqual(cl.queryset.query.select_related, {"child": {}})
def test_select_related_as_tuple(self):
ia = InvitationAdmin(Invitation, custom_site)
- request = self.factory.get('/invitation/')
+ request = self.factory.get("/invitation/")
request.user = self.superuser
cl = ia.get_changelist_instance(request)
- self.assertEqual(cl.queryset.query.select_related, {'player': {}})
+ self.assertEqual(cl.queryset.query.select_related, {"player": {}})
def test_select_related_as_empty_tuple(self):
ia = InvitationAdmin(Invitation, custom_site)
ia.list_select_related = ()
- request = self.factory.get('/invitation/')
+ request = self.factory.get("/invitation/")
request.user = self.superuser
cl = ia.get_changelist_instance(request)
self.assertIs(cl.queryset.query.select_related, False)
def test_get_select_related_custom_method(self):
class GetListSelectRelatedAdmin(admin.ModelAdmin):
- list_display = ('band', 'player')
+ list_display = ("band", "player")
def get_list_select_related(self, request):
- return ('band', 'player')
+ return ("band", "player")
ia = GetListSelectRelatedAdmin(Invitation, custom_site)
- request = self.factory.get('/invitation/')
+ request = self.factory.get("/invitation/")
request.user = self.superuser
cl = ia.get_changelist_instance(request)
- self.assertEqual(cl.queryset.query.select_related, {'player': {}, 'band': {}})
+ self.assertEqual(cl.queryset.query.select_related, {"player": {}, "band": {}})
def test_many_search_terms(self):
- parent = Parent.objects.create(name='Mary')
- Child.objects.create(parent=parent, name='Danielle')
- Child.objects.create(parent=parent, name='Daniel')
+ parent = Parent.objects.create(name="Mary")
+ Child.objects.create(parent=parent, name="Danielle")
+ Child.objects.create(parent=parent, name="Daniel")
m = ParentAdmin(Parent, custom_site)
- request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel ' * 80})
+ request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel " * 80})
request.user = self.superuser
cl = m.get_changelist_instance(request)
with CaptureQueriesContext(connection) as context:
object_count = cl.queryset.count()
self.assertEqual(object_count, 1)
- self.assertEqual(context.captured_queries[0]['sql'].count('JOIN'), 1)
+ self.assertEqual(context.captured_queries[0]["sql"].count("JOIN"), 1)
def test_related_field_multiple_search_terms(self):
"""
Searches over multi-valued relationships return rows from related
models only when all searched fields match that row.
"""
- parent = Parent.objects.create(name='Mary')
- Child.objects.create(parent=parent, name='Danielle', age=18)
- Child.objects.create(parent=parent, name='Daniel', age=19)
+ parent = Parent.objects.create(name="Mary")
+ Child.objects.create(parent=parent, name="Danielle", age=18)
+ Child.objects.create(parent=parent, name="Daniel", age=19)
m = ParentAdminTwoSearchFields(Parent, custom_site)
- request = self.factory.get('/parent/', data={SEARCH_VAR: 'danielle 19'})
+ request = self.factory.get("/parent/", data={SEARCH_VAR: "danielle 19"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertEqual(cl.queryset.count(), 0)
- request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel 19'})
+ request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel 19"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertEqual(cl.queryset.count(), 1)
@@ -194,78 +231,108 @@ class ChangeListTests(TestCase):
Regression test for #14982: EMPTY_CHANGELIST_VALUE should be honored
for relationship fields
"""
- new_child = Child.objects.create(name='name', parent=None)
- request = self.factory.get('/child/')
+ new_child = Child.objects.create(name="name", parent=None)
+ request = self.factory.get("/child/")
request.user = self.superuser
m = ChildAdmin(Child, custom_site)
cl = m.get_changelist_instance(request)
cl.formset = None
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl, 'opts': Child._meta})
+ template = Template(
+ "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}"
+ )
+ context = Context({"cl": cl, "opts": Child._meta})
table_output = template.render(context)
- link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = build_tbody_html(new_child.id, link, '<td class="field-parent nowrap">-</td>')
- self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output)
+ link = reverse("admin:admin_changelist_child_change", args=(new_child.id,))
+ row_html = build_tbody_html(
+ new_child.id, link, '<td class="field-parent nowrap">-</td>'
+ )
+ self.assertNotEqual(
+ table_output.find(row_html),
+ -1,
+ "Failed to find expected row element: %s" % table_output,
+ )
def test_result_list_set_empty_value_display_on_admin_site(self):
"""
Empty value display can be set on AdminSite.
"""
- new_child = Child.objects.create(name='name', parent=None)
- request = self.factory.get('/child/')
+ new_child = Child.objects.create(name="name", parent=None)
+ request = self.factory.get("/child/")
request.user = self.superuser
# Set a new empty display value on AdminSite.
- admin.site.empty_value_display = '???'
+ admin.site.empty_value_display = "???"
m = ChildAdmin(Child, admin.site)
cl = m.get_changelist_instance(request)
cl.formset = None
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl, 'opts': Child._meta})
+ template = Template(
+ "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}"
+ )
+ context = Context({"cl": cl, "opts": Child._meta})
table_output = template.render(context)
- link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = build_tbody_html(new_child.id, link, '<td class="field-parent nowrap">???</td>')
- self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output)
+ link = reverse("admin:admin_changelist_child_change", args=(new_child.id,))
+ row_html = build_tbody_html(
+ new_child.id, link, '<td class="field-parent nowrap">???</td>'
+ )
+ self.assertNotEqual(
+ table_output.find(row_html),
+ -1,
+ "Failed to find expected row element: %s" % table_output,
+ )
def test_result_list_set_empty_value_display_in_model_admin(self):
"""
Empty value display can be set in ModelAdmin or individual fields.
"""
- new_child = Child.objects.create(name='name', parent=None)
- request = self.factory.get('/child/')
+ new_child = Child.objects.create(name="name", parent=None)
+ request = self.factory.get("/child/")
request.user = self.superuser
m = EmptyValueChildAdmin(Child, admin.site)
cl = m.get_changelist_instance(request)
cl.formset = None
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl, 'opts': Child._meta})
+ template = Template(
+ "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}"
+ )
+ context = Context({"cl": cl, "opts": Child._meta})
table_output = template.render(context)
- link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
+ link = reverse("admin:admin_changelist_child_change", args=(new_child.id,))
row_html = build_tbody_html(
new_child.id,
link,
'<td class="field-age_display">&amp;dagger;</td>'
- '<td class="field-age">-empty-</td>'
+ '<td class="field-age">-empty-</td>',
+ )
+ self.assertNotEqual(
+ table_output.find(row_html),
+ -1,
+ "Failed to find expected row element: %s" % table_output,
)
- self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output)
def test_result_list_html(self):
"""
Inclusion tag result_list generates a table when with default
ModelAdmin settings.
"""
- new_parent = Parent.objects.create(name='parent')
- new_child = Child.objects.create(name='name', parent=new_parent)
- request = self.factory.get('/child/')
+ new_parent = Parent.objects.create(name="parent")
+ new_child = Child.objects.create(name="name", parent=new_parent)
+ request = self.factory.get("/child/")
request.user = self.superuser
m = ChildAdmin(Child, custom_site)
cl = m.get_changelist_instance(request)
cl.formset = None
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl, 'opts': Child._meta})
+ template = Template(
+ "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}"
+ )
+ context = Context({"cl": cl, "opts": Child._meta})
table_output = template.render(context)
- link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = build_tbody_html(new_child.id, link, '<td class="field-parent nowrap">%s</td>' % new_parent)
- self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output)
+ link = reverse("admin:admin_changelist_child_change", args=(new_child.id,))
+ row_html = build_tbody_html(
+ new_child.id, link, '<td class="field-parent nowrap">%s</td>' % new_parent
+ )
+ self.assertNotEqual(
+ table_output.find(row_html),
+ -1,
+ "Failed to find expected row element: %s" % table_output,
+ )
def test_result_list_editable_html(self):
"""
@@ -276,29 +343,33 @@ class ChangeListTests(TestCase):
when list_editable is enabled are rendered in a div outside the
table.
"""
- new_parent = Parent.objects.create(name='parent')
- new_child = Child.objects.create(name='name', parent=new_parent)
- request = self.factory.get('/child/')
+ new_parent = Parent.objects.create(name="parent")
+ new_child = Child.objects.create(name="name", parent=new_parent)
+ request = self.factory.get("/child/")
request.user = self.superuser
m = ChildAdmin(Child, custom_site)
# Test with list_editable fields
- m.list_display = ['id', 'name', 'parent']
- m.list_display_links = ['id']
- m.list_editable = ['name']
+ m.list_display = ["id", "name", "parent"]
+ m.list_display_links = ["id"]
+ m.list_editable = ["name"]
cl = m.get_changelist_instance(request)
FormSet = m.get_changelist_formset(request)
cl.formset = FormSet(queryset=cl.result_list)
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl, 'opts': Child._meta})
+ template = Template(
+ "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}"
+ )
+ context = Context({"cl": cl, "opts": Child._meta})
table_output = template.render(context)
# make sure that hidden fields are in the correct place
hiddenfields_div = (
'<div class="hiddenfields">'
'<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id">'
- '</div>'
+ "</div>"
) % new_child.id
- self.assertInHTML(hiddenfields_div, table_output, msg_prefix='Failed to find hidden fields')
+ self.assertInHTML(
+ hiddenfields_div, table_output, msg_prefix="Failed to find hidden fields"
+ )
# make sure that list editable fields are rendered in divs correctly
editable_name_field = (
@@ -315,26 +386,26 @@ class ChangeListTests(TestCase):
"""
Regression test for #14312: list_editable with pagination
"""
- new_parent = Parent.objects.create(name='parent')
+ new_parent = Parent.objects.create(name="parent")
for i in range(1, 201):
- Child.objects.create(name='name %s' % i, parent=new_parent)
- request = self.factory.get('/child/', data={'p': -1}) # Anything outside range
+ Child.objects.create(name="name %s" % i, parent=new_parent)
+ request = self.factory.get("/child/", data={"p": -1}) # Anything outside range
request.user = self.superuser
m = ChildAdmin(Child, custom_site)
# Test with list_editable fields
- m.list_display = ['id', 'name', 'parent']
- m.list_display_links = ['id']
- m.list_editable = ['name']
+ m.list_display = ["id", "name", "parent"]
+ m.list_display_links = ["id"]
+ m.list_editable = ["name"]
with self.assertRaises(IncorrectLookupParameters):
m.get_changelist_instance(request)
def test_custom_paginator(self):
- new_parent = Parent.objects.create(name='parent')
+ new_parent = Parent.objects.create(name="parent")
for i in range(1, 201):
- Child.objects.create(name='name %s' % i, parent=new_parent)
+ Child.objects.create(name="name %s" % i, parent=new_parent)
- request = self.factory.get('/child/')
+ request = self.factory.get("/child/")
request.user = self.superuser
m = CustomPaginationAdmin(Child, custom_site)
@@ -347,14 +418,14 @@ class ChangeListTests(TestCase):
Regression test for #13902: When using a ManyToMany in list_filter,
results shouldn't appear more than once. Basic ManyToMany.
"""
- blues = Genre.objects.create(name='Blues')
- band = Band.objects.create(name='B.B. King Review', nr_of_members=11)
+ blues = Genre.objects.create(name="Blues")
+ band = Band.objects.create(name="B.B. King Review", nr_of_members=11)
band.genres.add(blues)
band.genres.add(blues)
m = BandAdmin(Band, custom_site)
- request = self.factory.get('/band/', data={'genres': blues.pk})
+ request = self.factory.get("/band/", data={"genres": blues.pk})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -372,13 +443,13 @@ class ChangeListTests(TestCase):
Regression test for #13902: When using a ManyToMany in list_filter,
results shouldn't appear more than once. With an intermediate model.
"""
- lead = Musician.objects.create(name='Vox')
- band = Group.objects.create(name='The Hype')
- Membership.objects.create(group=band, music=lead, role='lead voice')
- Membership.objects.create(group=band, music=lead, role='bass player')
+ lead = Musician.objects.create(name="Vox")
+ band = Group.objects.create(name="The Hype")
+ Membership.objects.create(group=band, music=lead, role="lead voice")
+ Membership.objects.create(group=band, music=lead, role="bass player")
m = GroupAdmin(Group, custom_site)
- request = self.factory.get('/group/', data={'members': lead.pk})
+ request = self.factory.get("/group/", data={"members": lead.pk})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -396,14 +467,14 @@ class ChangeListTests(TestCase):
When using a ManyToMany in list_filter at the second level behind a
ForeignKey, results shouldn't appear more than once.
"""
- lead = Musician.objects.create(name='Vox')
- band = Group.objects.create(name='The Hype')
- Concert.objects.create(name='Woodstock', group=band)
- Membership.objects.create(group=band, music=lead, role='lead voice')
- Membership.objects.create(group=band, music=lead, role='bass player')
+ lead = Musician.objects.create(name="Vox")
+ band = Group.objects.create(name="The Hype")
+ Concert.objects.create(name="Woodstock", group=band)
+ Membership.objects.create(group=band, music=lead, role="lead voice")
+ Membership.objects.create(group=band, music=lead, role="bass player")
m = ConcertAdmin(Concert, custom_site)
- request = self.factory.get('/concert/', data={'group__members': lead.pk})
+ request = self.factory.get("/concert/", data={"group__members": lead.pk})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -422,13 +493,13 @@ class ChangeListTests(TestCase):
results shouldn't appear more than once. Model managed in the
admin inherits from the one that defines the relationship.
"""
- lead = Musician.objects.create(name='John')
- four = Quartet.objects.create(name='The Beatles')
- Membership.objects.create(group=four, music=lead, role='lead voice')
- Membership.objects.create(group=four, music=lead, role='guitar player')
+ lead = Musician.objects.create(name="John")
+ four = Quartet.objects.create(name="The Beatles")
+ Membership.objects.create(group=four, music=lead, role="lead voice")
+ Membership.objects.create(group=four, music=lead, role="guitar player")
m = QuartetAdmin(Quartet, custom_site)
- request = self.factory.get('/quartet/', data={'members': lead.pk})
+ request = self.factory.get("/quartet/", data={"members": lead.pk})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -447,13 +518,13 @@ class ChangeListTests(TestCase):
results shouldn't appear more than once. Target of the relationship
inherits from another.
"""
- lead = ChordsMusician.objects.create(name='Player A')
- three = ChordsBand.objects.create(name='The Chords Trio')
- Invitation.objects.create(band=three, player=lead, instrument='guitar')
- Invitation.objects.create(band=three, player=lead, instrument='bass')
+ lead = ChordsMusician.objects.create(name="Player A")
+ three = ChordsBand.objects.create(name="The Chords Trio")
+ Invitation.objects.create(band=three, player=lead, instrument="guitar")
+ Invitation.objects.create(band=three, player=lead, instrument="bass")
m = ChordsBandAdmin(ChordsBand, custom_site)
- request = self.factory.get('/chordsband/', data={'members': lead.pk})
+ request = self.factory.get("/chordsband/", data={"members": lead.pk})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -471,13 +542,13 @@ class ChangeListTests(TestCase):
Regressions tests for #15819: If a field listed in list_filters is a
non-unique related object, results shouldn't appear more than once.
"""
- parent = Parent.objects.create(name='Mary')
+ parent = Parent.objects.create(name="Mary")
# Two children with the same name
- Child.objects.create(parent=parent, name='Daniel')
- Child.objects.create(parent=parent, name='Daniel')
+ Child.objects.create(parent=parent, name="Daniel")
+ Child.objects.create(parent=parent, name="Daniel")
m = ParentAdmin(Parent, custom_site)
- request = self.factory.get('/parent/', data={'child__name': 'Daniel'})
+ request = self.factory.get("/parent/", data={"child__name": "Daniel"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -491,12 +562,12 @@ class ChangeListTests(TestCase):
def test_changelist_search_form_validation(self):
m = ConcertAdmin(Concert, custom_site)
tests = [
- ({SEARCH_VAR: '\x00'}, 'Null characters are not allowed.'),
- ({SEARCH_VAR: 'some\x00thing'}, 'Null characters are not allowed.'),
+ ({SEARCH_VAR: "\x00"}, "Null characters are not allowed."),
+ ({SEARCH_VAR: "some\x00thing"}, "Null characters are not allowed."),
]
for case, error in tests:
with self.subTest(case=case):
- request = self.factory.get('/concert/', case)
+ request = self.factory.get("/concert/", case)
request.user = self.superuser
request._messages = CookieStorage(request)
m.get_changelist_instance(request)
@@ -509,12 +580,12 @@ class ChangeListTests(TestCase):
Regressions tests for #15819: If a field listed in search_fields
is a non-unique related object, Exists() must be applied.
"""
- parent = Parent.objects.create(name='Mary')
- Child.objects.create(parent=parent, name='Danielle')
- Child.objects.create(parent=parent, name='Daniel')
+ parent = Parent.objects.create(name="Mary")
+ Child.objects.create(parent=parent, name="Danielle")
+ Child.objects.create(parent=parent, name="Daniel")
m = ParentAdmin(Parent, custom_site)
- request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel'})
+ request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -531,14 +602,14 @@ class ChangeListTests(TestCase):
ForeignKey, Exists() must be applied and results shouldn't appear more
than once.
"""
- lead = Musician.objects.create(name='Vox')
- band = Group.objects.create(name='The Hype')
- Concert.objects.create(name='Woodstock', group=band)
- Membership.objects.create(group=band, music=lead, role='lead voice')
- Membership.objects.create(group=band, music=lead, role='bass player')
+ lead = Musician.objects.create(name="Vox")
+ band = Group.objects.create(name="The Hype")
+ Concert.objects.create(name="Woodstock", group=band)
+ Membership.objects.create(group=band, music=lead, role="lead voice")
+ Membership.objects.create(group=band, music=lead, role="bass player")
m = ConcertAdmin(Concert, custom_site)
- request = self.factory.get('/concert/', data={SEARCH_VAR: 'vox'})
+ request = self.factory.get("/concert/", data={SEARCH_VAR: "vox"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
@@ -554,139 +625,143 @@ class ChangeListTests(TestCase):
All rows containing each of the searched words are returned, where each
word must be in one of search_fields.
"""
- band_duo = Group.objects.create(name='Duo')
- band_hype = Group.objects.create(name='The Hype')
- mary = Musician.objects.create(name='Mary Halvorson')
- jonathan = Musician.objects.create(name='Jonathan Finlayson')
+ band_duo = Group.objects.create(name="Duo")
+ band_hype = Group.objects.create(name="The Hype")
+ mary = Musician.objects.create(name="Mary Halvorson")
+ jonathan = Musician.objects.create(name="Jonathan Finlayson")
band_duo.members.set([mary, jonathan])
- Concert.objects.create(name='Tiny desk concert', group=band_duo)
- Concert.objects.create(name='Woodstock concert', group=band_hype)
+ Concert.objects.create(name="Tiny desk concert", group=band_duo)
+ Concert.objects.create(name="Woodstock concert", group=band_hype)
# FK lookup.
concert_model_admin = ConcertAdmin(Concert, custom_site)
- concert_model_admin.search_fields = ['group__name', 'name']
+ concert_model_admin.search_fields = ["group__name", "name"]
# Reverse FK lookup.
group_model_admin = GroupAdmin(Group, custom_site)
- group_model_admin.search_fields = ['name', 'concert__name', 'members__name']
+ group_model_admin.search_fields = ["name", "concert__name", "members__name"]
for search_string, result_count in (
- ('Duo Concert', 1),
- ('Tiny Desk Concert', 1),
- ('Concert', 2),
- ('Other Concert', 0),
- ('Duo Woodstock', 0),
+ ("Duo Concert", 1),
+ ("Tiny Desk Concert", 1),
+ ("Concert", 2),
+ ("Other Concert", 0),
+ ("Duo Woodstock", 0),
):
with self.subTest(search_string=search_string):
# FK lookup.
- request = self.factory.get('/concert/', data={SEARCH_VAR: search_string})
+ request = self.factory.get(
+ "/concert/", data={SEARCH_VAR: search_string}
+ )
request.user = self.superuser
- concert_changelist = concert_model_admin.get_changelist_instance(request)
+ concert_changelist = concert_model_admin.get_changelist_instance(
+ request
+ )
self.assertEqual(concert_changelist.queryset.count(), result_count)
# Reverse FK lookup.
- request = self.factory.get('/group/', data={SEARCH_VAR: search_string})
+ request = self.factory.get("/group/", data={SEARCH_VAR: search_string})
request.user = self.superuser
group_changelist = group_model_admin.get_changelist_instance(request)
self.assertEqual(group_changelist.queryset.count(), result_count)
# Many-to-many lookup.
for search_string, result_count in (
- ('Finlayson Duo Tiny', 1),
- ('Finlayson', 1),
- ('Finlayson Hype', 0),
- ('Jonathan Finlayson Duo', 1),
- ('Mary Jonathan Duo', 0),
- ('Oscar Finlayson Duo', 0),
+ ("Finlayson Duo Tiny", 1),
+ ("Finlayson", 1),
+ ("Finlayson Hype", 0),
+ ("Jonathan Finlayson Duo", 1),
+ ("Mary Jonathan Duo", 0),
+ ("Oscar Finlayson Duo", 0),
):
with self.subTest(search_string=search_string):
- request = self.factory.get('/group/', data={SEARCH_VAR: search_string})
+ request = self.factory.get("/group/", data={SEARCH_VAR: search_string})
request.user = self.superuser
group_changelist = group_model_admin.get_changelist_instance(request)
self.assertEqual(group_changelist.queryset.count(), result_count)
def test_pk_in_search_fields(self):
- band = Group.objects.create(name='The Hype')
- Concert.objects.create(name='Woodstock', group=band)
+ band = Group.objects.create(name="The Hype")
+ Concert.objects.create(name="Woodstock", group=band)
m = ConcertAdmin(Concert, custom_site)
- m.search_fields = ['group__pk']
+ m.search_fields = ["group__pk"]
- request = self.factory.get('/concert/', data={SEARCH_VAR: band.pk})
+ request = self.factory.get("/concert/", data={SEARCH_VAR: band.pk})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertEqual(cl.queryset.count(), 1)
- request = self.factory.get('/concert/', data={SEARCH_VAR: band.pk + 5})
+ request = self.factory.get("/concert/", data={SEARCH_VAR: band.pk + 5})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertEqual(cl.queryset.count(), 0)
def test_builtin_lookup_in_search_fields(self):
- band = Group.objects.create(name='The Hype')
- concert = Concert.objects.create(name='Woodstock', group=band)
+ band = Group.objects.create(name="The Hype")
+ concert = Concert.objects.create(name="Woodstock", group=band)
m = ConcertAdmin(Concert, custom_site)
- m.search_fields = ['name__iexact']
+ m.search_fields = ["name__iexact"]
- request = self.factory.get('/', data={SEARCH_VAR: 'woodstock'})
+ request = self.factory.get("/", data={SEARCH_VAR: "woodstock"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [concert])
- request = self.factory.get('/', data={SEARCH_VAR: 'wood'})
+ request = self.factory.get("/", data={SEARCH_VAR: "wood"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [])
def test_custom_lookup_in_search_fields(self):
- band = Group.objects.create(name='The Hype')
- concert = Concert.objects.create(name='Woodstock', group=band)
+ band = Group.objects.create(name="The Hype")
+ concert = Concert.objects.create(name="Woodstock", group=band)
m = ConcertAdmin(Concert, custom_site)
- m.search_fields = ['group__name__cc']
- with register_lookup(Field, Contains, lookup_name='cc'):
- request = self.factory.get('/', data={SEARCH_VAR: 'Hype'})
+ m.search_fields = ["group__name__cc"]
+ with register_lookup(Field, Contains, lookup_name="cc"):
+ request = self.factory.get("/", data={SEARCH_VAR: "Hype"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [concert])
- request = self.factory.get('/', data={SEARCH_VAR: 'Woodstock'})
+ request = self.factory.get("/", data={SEARCH_VAR: "Woodstock"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [])
def test_spanning_relations_with_custom_lookup_in_search_fields(self):
- hype = Group.objects.create(name='The Hype')
- concert = Concert.objects.create(name='Woodstock', group=hype)
- vox = Musician.objects.create(name='Vox', age=20)
+ hype = Group.objects.create(name="The Hype")
+ concert = Concert.objects.create(name="Woodstock", group=hype)
+ vox = Musician.objects.create(name="Vox", age=20)
Membership.objects.create(music=vox, group=hype)
# Register a custom lookup on IntegerField to ensure that field
# traversing logic in ModelAdmin.get_search_results() works.
- with register_lookup(IntegerField, Exact, lookup_name='exactly'):
+ with register_lookup(IntegerField, Exact, lookup_name="exactly"):
m = ConcertAdmin(Concert, custom_site)
- m.search_fields = ['group__members__age__exactly']
+ m.search_fields = ["group__members__age__exactly"]
- request = self.factory.get('/', data={SEARCH_VAR: '20'})
+ request = self.factory.get("/", data={SEARCH_VAR: "20"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [concert])
- request = self.factory.get('/', data={SEARCH_VAR: '21'})
+ request = self.factory.get("/", data={SEARCH_VAR: "21"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [])
def test_custom_lookup_with_pk_shortcut(self):
- self.assertEqual(CharPK._meta.pk.name, 'char_pk') # Not equal to 'pk'.
+ self.assertEqual(CharPK._meta.pk.name, "char_pk") # Not equal to 'pk'.
m = admin.ModelAdmin(CustomIdUser, custom_site)
- abc = CharPK.objects.create(char_pk='abc')
- abcd = CharPK.objects.create(char_pk='abcd')
+ abc = CharPK.objects.create(char_pk="abc")
+ abcd = CharPK.objects.create(char_pk="abcd")
m = admin.ModelAdmin(CharPK, custom_site)
- m.search_fields = ['pk__exact']
+ m.search_fields = ["pk__exact"]
- request = self.factory.get('/', data={SEARCH_VAR: 'abc'})
+ request = self.factory.get("/", data={SEARCH_VAR: "abc"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [abc])
- request = self.factory.get('/', data={SEARCH_VAR: 'abcd'})
+ request = self.factory.get("/", data={SEARCH_VAR: "abcd"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
self.assertCountEqual(cl.queryset, [abcd])
@@ -697,29 +772,29 @@ class ChangeListTests(TestCase):
the changelist's query shouldn't have Exists().
"""
m = BandAdmin(Band, custom_site)
- for lookup_params in ({}, {'name': 'test'}):
- request = self.factory.get('/band/', lookup_params)
+ for lookup_params in ({}, {"name": "test"}):
+ request = self.factory.get("/band/", lookup_params)
request.user = self.superuser
cl = m.get_changelist_instance(request)
- self.assertNotIn(' EXISTS', str(cl.queryset.query))
+ self.assertNotIn(" EXISTS", str(cl.queryset.query))
# A ManyToManyField in params does have Exists() applied.
- request = self.factory.get('/band/', {'genres': '0'})
+ request = self.factory.get("/band/", {"genres": "0"})
request.user = self.superuser
cl = m.get_changelist_instance(request)
- self.assertIn(' EXISTS', str(cl.queryset.query))
+ self.assertIn(" EXISTS", str(cl.queryset.query))
def test_pagination(self):
"""
Regression tests for #12893: Pagination in admins changelist doesn't
use queryset set by modeladmin.
"""
- parent = Parent.objects.create(name='anything')
+ parent = Parent.objects.create(name="anything")
for i in range(1, 31):
- Child.objects.create(name='name %s' % i, parent=parent)
- Child.objects.create(name='filtered %s' % i, parent=parent)
+ Child.objects.create(name="name %s" % i, parent=parent)
+ Child.objects.create(name="filtered %s" % i, parent=parent)
- request = self.factory.get('/child/')
+ request = self.factory.get("/child/")
request.user = self.superuser
# Test default queryset
@@ -743,7 +818,7 @@ class ChangeListTests(TestCase):
"""
self.client.force_login(self.superuser)
event = Event.objects.create(date=datetime.date.today())
- response = self.client.get(reverse('admin:admin_changelist_event_changelist'))
+ response = self.client.get(reverse("admin:admin_changelist_event_changelist"))
self.assertContains(response, formats.localize(event.date))
self.assertNotContains(response, str(event.date))
@@ -751,52 +826,52 @@ class ChangeListTests(TestCase):
"""
Regression tests for #14206: dynamic list_display support.
"""
- parent = Parent.objects.create(name='parent')
+ parent = Parent.objects.create(name="parent")
for i in range(10):
- Child.objects.create(name='child %s' % i, parent=parent)
+ Child.objects.create(name="child %s" % i, parent=parent)
- user_noparents = self._create_superuser('noparents')
- user_parents = self._create_superuser('parents')
+ user_noparents = self._create_superuser("noparents")
+ user_parents = self._create_superuser("parents")
# Test with user 'noparents'
m = custom_site._registry[Child]
- request = self._mocked_authenticated_request('/child/', user_noparents)
+ request = self._mocked_authenticated_request("/child/", user_noparents)
response = m.changelist_view(request)
- self.assertNotContains(response, 'Parent object')
+ self.assertNotContains(response, "Parent object")
list_display = m.get_list_display(request)
list_display_links = m.get_list_display_links(request, list_display)
- self.assertEqual(list_display, ['name', 'age'])
- self.assertEqual(list_display_links, ['name'])
+ self.assertEqual(list_display, ["name", "age"])
+ self.assertEqual(list_display_links, ["name"])
# Test with user 'parents'
m = DynamicListDisplayChildAdmin(Child, custom_site)
- request = self._mocked_authenticated_request('/child/', user_parents)
+ request = self._mocked_authenticated_request("/child/", user_parents)
response = m.changelist_view(request)
- self.assertContains(response, 'Parent object')
+ self.assertContains(response, "Parent object")
custom_site.unregister(Child)
list_display = m.get_list_display(request)
list_display_links = m.get_list_display_links(request, list_display)
- self.assertEqual(list_display, ('parent', 'name', 'age'))
- self.assertEqual(list_display_links, ['parent'])
+ self.assertEqual(list_display, ("parent", "name", "age"))
+ self.assertEqual(list_display_links, ["parent"])
# Test default implementation
custom_site.register(Child, ChildAdmin)
m = custom_site._registry[Child]
- request = self._mocked_authenticated_request('/child/', user_noparents)
+ request = self._mocked_authenticated_request("/child/", user_noparents)
response = m.changelist_view(request)
- self.assertContains(response, 'Parent object')
+ self.assertContains(response, "Parent object")
def test_show_all(self):
- parent = Parent.objects.create(name='anything')
+ parent = Parent.objects.create(name="anything")
for i in range(1, 31):
- Child.objects.create(name='name %s' % i, parent=parent)
- Child.objects.create(name='filtered %s' % i, parent=parent)
+ Child.objects.create(name="name %s" % i, parent=parent)
+ Child.objects.create(name="filtered %s" % i, parent=parent)
# Add "show all" parameter to request
- request = self.factory.get('/child/', data={ALL_VAR: ''})
+ request = self.factory.get("/child/", data={ALL_VAR: ""})
request.user = self.superuser
# Test valid "show all" request (number of total objects is under max)
@@ -820,52 +895,52 @@ class ChangeListTests(TestCase):
"""
Regression tests for #16257: dynamic list_display_links support.
"""
- parent = Parent.objects.create(name='parent')
+ parent = Parent.objects.create(name="parent")
for i in range(1, 10):
- Child.objects.create(id=i, name='child %s' % i, parent=parent, age=i)
+ Child.objects.create(id=i, name="child %s" % i, parent=parent, age=i)
m = DynamicListDisplayLinksChildAdmin(Child, custom_site)
- superuser = self._create_superuser('superuser')
- request = self._mocked_authenticated_request('/child/', superuser)
+ superuser = self._create_superuser("superuser")
+ request = self._mocked_authenticated_request("/child/", superuser)
response = m.changelist_view(request)
for i in range(1, 10):
- link = reverse('admin:admin_changelist_child_change', args=(i,))
+ link = reverse("admin:admin_changelist_child_change", args=(i,))
self.assertContains(response, '<a href="%s">%s</a>' % (link, i))
list_display = m.get_list_display(request)
list_display_links = m.get_list_display_links(request, list_display)
- self.assertEqual(list_display, ('parent', 'name', 'age'))
- self.assertEqual(list_display_links, ['age'])
+ self.assertEqual(list_display, ("parent", "name", "age"))
+ self.assertEqual(list_display_links, ["age"])
def test_no_list_display_links(self):
"""#15185 -- Allow no links from the 'change list' view grid."""
- p = Parent.objects.create(name='parent')
+ p = Parent.objects.create(name="parent")
m = NoListDisplayLinksParentAdmin(Parent, custom_site)
- superuser = self._create_superuser('superuser')
- request = self._mocked_authenticated_request('/parent/', superuser)
+ superuser = self._create_superuser("superuser")
+ request = self._mocked_authenticated_request("/parent/", superuser)
response = m.changelist_view(request)
- link = reverse('admin:admin_changelist_parent_change', args=(p.pk,))
+ link = reverse("admin:admin_changelist_parent_change", args=(p.pk,))
self.assertNotContains(response, '<a href="%s">' % link)
def test_clear_all_filters_link(self):
self.client.force_login(self.superuser)
- url = reverse('admin:auth_user_changelist')
+ url = reverse("admin:auth_user_changelist")
response = self.client.get(url)
- self.assertNotContains(response, '&#10006; Clear all filters')
+ self.assertNotContains(response, "&#10006; Clear all filters")
link = '<a href="%s">&#10006; Clear all filters</a>'
for data, href in (
- ({'is_staff__exact': '0'}, '?'),
+ ({"is_staff__exact": "0"}, "?"),
(
- {'is_staff__exact': '0', 'username__startswith': 'test'},
- '?username__startswith=test',
+ {"is_staff__exact": "0", "username__startswith": "test"},
+ "?username__startswith=test",
),
(
- {'is_staff__exact': '0', SEARCH_VAR: 'test'},
- '?%s=test' % SEARCH_VAR,
+ {"is_staff__exact": "0", SEARCH_VAR: "test"},
+ "?%s=test" % SEARCH_VAR,
),
(
- {'is_staff__exact': '0', IS_POPUP_VAR: 'id'},
- '?%s=id' % IS_POPUP_VAR,
+ {"is_staff__exact": "0", IS_POPUP_VAR: "id"},
+ "?%s=id" % IS_POPUP_VAR,
),
):
with self.subTest(data=data):
@@ -874,19 +949,19 @@ class ChangeListTests(TestCase):
def test_clear_all_filters_link_callable_filter(self):
self.client.force_login(self.superuser)
- url = reverse('admin:admin_changelist_band_changelist')
+ url = reverse("admin:admin_changelist_band_changelist")
response = self.client.get(url)
- self.assertNotContains(response, '&#10006; Clear all filters')
+ self.assertNotContains(response, "&#10006; Clear all filters")
link = '<a href="%s">&#10006; Clear all filters</a>'
for data, href in (
- ({'nr_of_members_partition': '5'}, '?'),
+ ({"nr_of_members_partition": "5"}, "?"),
(
- {'nr_of_members_partition': 'more', 'name__startswith': 'test'},
- '?name__startswith=test',
+ {"nr_of_members_partition": "more", "name__startswith": "test"},
+ "?name__startswith=test",
),
(
- {'nr_of_members_partition': '5', IS_POPUP_VAR: 'id'},
- '?%s=id' % IS_POPUP_VAR,
+ {"nr_of_members_partition": "5", IS_POPUP_VAR: "id"},
+ "?%s=id" % IS_POPUP_VAR,
),
):
with self.subTest(data=data):
@@ -895,28 +970,28 @@ class ChangeListTests(TestCase):
def test_no_clear_all_filters_link(self):
self.client.force_login(self.superuser)
- url = reverse('admin:auth_user_changelist')
- link = '>&#10006; Clear all filters</a>'
+ url = reverse("admin:auth_user_changelist")
+ link = ">&#10006; Clear all filters</a>"
for data in (
- {SEARCH_VAR: 'test'},
- {ORDER_VAR: '-1'},
- {TO_FIELD_VAR: 'id'},
- {PAGE_VAR: '1'},
- {IS_POPUP_VAR: '1'},
- {'username__startswith': 'test'},
+ {SEARCH_VAR: "test"},
+ {ORDER_VAR: "-1"},
+ {TO_FIELD_VAR: "id"},
+ {PAGE_VAR: "1"},
+ {IS_POPUP_VAR: "1"},
+ {"username__startswith": "test"},
):
with self.subTest(data=data):
response = self.client.get(url, data=data)
self.assertNotContains(response, link)
def test_tuple_list_display(self):
- swallow = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')
- swallow2 = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')
+ swallow = Swallow.objects.create(origin="Africa", load="12.34", speed="22.2")
+ swallow2 = Swallow.objects.create(origin="Africa", load="12.34", speed="22.2")
swallow_o2o = SwallowOneToOne.objects.create(swallow=swallow2)
model_admin = SwallowAdmin(Swallow, custom_site)
- superuser = self._create_superuser('superuser')
- request = self._mocked_authenticated_request('/swallow/', superuser)
+ superuser = self._create_superuser("superuser")
+ request = self._mocked_authenticated_request("/swallow/", superuser)
response = model_admin.changelist_view(request)
# just want to ensure it doesn't blow up during rendering
self.assertContains(response, str(swallow.origin))
@@ -924,7 +999,9 @@ class ChangeListTests(TestCase):
self.assertContains(response, str(swallow.speed))
# Reverse one-to-one relations should work.
self.assertContains(response, '<td class="field-swallowonetoone">-</td>')
- self.assertContains(response, '<td class="field-swallowonetoone">%s</td>' % swallow_o2o)
+ self.assertContains(
+ response, '<td class="field-swallowonetoone">%s</td>' % swallow_o2o
+ )
def test_multiuser_edit(self):
"""
@@ -945,150 +1022,152 @@ class ChangeListTests(TestCase):
# Setup the test to reflect the DB state after step 2 where User2 has
# edited the first swallow object's speed from '4' to '1'.
- a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
- b = Swallow.objects.create(origin='Swallow B', load=2, speed=2)
- c = Swallow.objects.create(origin='Swallow C', load=5, speed=5)
- d = Swallow.objects.create(origin='Swallow D', load=9, speed=9)
+ a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)
+ b = Swallow.objects.create(origin="Swallow B", load=2, speed=2)
+ c = Swallow.objects.create(origin="Swallow C", load=5, speed=5)
+ d = Swallow.objects.create(origin="Swallow D", load=9, speed=9)
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
self.client.force_login(superuser)
- changelist_url = reverse('admin:admin_changelist_swallow_changelist')
+ changelist_url = reverse("admin:admin_changelist_swallow_changelist")
# Send the POST from User1 for step 3. It's still using the changelist
# ordering from before User2's edits in step 2.
data = {
- 'form-TOTAL_FORMS': '3',
- 'form-INITIAL_FORMS': '3',
- 'form-MIN_NUM_FORMS': '0',
- 'form-MAX_NUM_FORMS': '1000',
- 'form-0-uuid': str(d.pk),
- 'form-1-uuid': str(c.pk),
- 'form-2-uuid': str(a.pk),
- 'form-0-load': '9.0',
- 'form-0-speed': '9.0',
- 'form-1-load': '5.0',
- 'form-1-speed': '5.0',
- 'form-2-load': '5.0',
- 'form-2-speed': '4.0',
- '_save': 'Save',
+ "form-TOTAL_FORMS": "3",
+ "form-INITIAL_FORMS": "3",
+ "form-MIN_NUM_FORMS": "0",
+ "form-MAX_NUM_FORMS": "1000",
+ "form-0-uuid": str(d.pk),
+ "form-1-uuid": str(c.pk),
+ "form-2-uuid": str(a.pk),
+ "form-0-load": "9.0",
+ "form-0-speed": "9.0",
+ "form-1-load": "5.0",
+ "form-1-speed": "5.0",
+ "form-2-load": "5.0",
+ "form-2-speed": "4.0",
+ "_save": "Save",
}
- response = self.client.post(changelist_url, data, follow=True, extra={'o': '-2'})
+ response = self.client.post(
+ changelist_url, data, follow=True, extra={"o": "-2"}
+ )
# The object User1 edited in step 3 is displayed on the changelist and
# has the correct edits applied.
- self.assertContains(response, '1 swallow was changed successfully.')
+ self.assertContains(response, "1 swallow was changed successfully.")
self.assertContains(response, a.origin)
a.refresh_from_db()
- self.assertEqual(a.load, float(data['form-2-load']))
- self.assertEqual(a.speed, float(data['form-2-speed']))
+ self.assertEqual(a.load, float(data["form-2-load"]))
+ self.assertEqual(a.speed, float(data["form-2-speed"]))
b.refresh_from_db()
self.assertEqual(b.load, 2)
self.assertEqual(b.speed, 2)
c.refresh_from_db()
- self.assertEqual(c.load, float(data['form-1-load']))
- self.assertEqual(c.speed, float(data['form-1-speed']))
+ self.assertEqual(c.load, float(data["form-1-load"]))
+ self.assertEqual(c.speed, float(data["form-1-speed"]))
d.refresh_from_db()
- self.assertEqual(d.load, float(data['form-0-load']))
- self.assertEqual(d.speed, float(data['form-0-speed']))
+ self.assertEqual(d.load, float(data["form-0-load"]))
+ self.assertEqual(d.speed, float(data["form-0-speed"]))
# No new swallows were created.
self.assertEqual(len(Swallow.objects.all()), 4)
def test_get_edited_object_ids(self):
- a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
- b = Swallow.objects.create(origin='Swallow B', load=2, speed=2)
- c = Swallow.objects.create(origin='Swallow C', load=5, speed=5)
- superuser = self._create_superuser('superuser')
+ a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)
+ b = Swallow.objects.create(origin="Swallow B", load=2, speed=2)
+ c = Swallow.objects.create(origin="Swallow C", load=5, speed=5)
+ superuser = self._create_superuser("superuser")
self.client.force_login(superuser)
- changelist_url = reverse('admin:admin_changelist_swallow_changelist')
+ changelist_url = reverse("admin:admin_changelist_swallow_changelist")
m = SwallowAdmin(Swallow, custom_site)
data = {
- 'form-TOTAL_FORMS': '3',
- 'form-INITIAL_FORMS': '3',
- 'form-MIN_NUM_FORMS': '0',
- 'form-MAX_NUM_FORMS': '1000',
- 'form-0-uuid': str(a.pk),
- 'form-1-uuid': str(b.pk),
- 'form-2-uuid': str(c.pk),
- 'form-0-load': '9.0',
- 'form-0-speed': '9.0',
- 'form-1-load': '5.0',
- 'form-1-speed': '5.0',
- 'form-2-load': '5.0',
- 'form-2-speed': '4.0',
- '_save': 'Save',
+ "form-TOTAL_FORMS": "3",
+ "form-INITIAL_FORMS": "3",
+ "form-MIN_NUM_FORMS": "0",
+ "form-MAX_NUM_FORMS": "1000",
+ "form-0-uuid": str(a.pk),
+ "form-1-uuid": str(b.pk),
+ "form-2-uuid": str(c.pk),
+ "form-0-load": "9.0",
+ "form-0-speed": "9.0",
+ "form-1-load": "5.0",
+ "form-1-speed": "5.0",
+ "form-2-load": "5.0",
+ "form-2-speed": "4.0",
+ "_save": "Save",
}
request = self.factory.post(changelist_url, data=data)
- pks = m._get_edited_object_pks(request, prefix='form')
+ pks = m._get_edited_object_pks(request, prefix="form")
self.assertEqual(sorted(pks), sorted([str(a.pk), str(b.pk), str(c.pk)]))
def test_get_list_editable_queryset(self):
- a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
- Swallow.objects.create(origin='Swallow B', load=2, speed=2)
+ a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)
+ Swallow.objects.create(origin="Swallow B", load=2, speed=2)
data = {
- 'form-TOTAL_FORMS': '2',
- 'form-INITIAL_FORMS': '2',
- 'form-MIN_NUM_FORMS': '0',
- 'form-MAX_NUM_FORMS': '1000',
- 'form-0-uuid': str(a.pk),
- 'form-0-load': '10',
- '_save': 'Save',
+ "form-TOTAL_FORMS": "2",
+ "form-INITIAL_FORMS": "2",
+ "form-MIN_NUM_FORMS": "0",
+ "form-MAX_NUM_FORMS": "1000",
+ "form-0-uuid": str(a.pk),
+ "form-0-load": "10",
+ "_save": "Save",
}
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
self.client.force_login(superuser)
- changelist_url = reverse('admin:admin_changelist_swallow_changelist')
+ changelist_url = reverse("admin:admin_changelist_swallow_changelist")
m = SwallowAdmin(Swallow, custom_site)
request = self.factory.post(changelist_url, data=data)
- queryset = m._get_list_editable_queryset(request, prefix='form')
+ queryset = m._get_list_editable_queryset(request, prefix="form")
self.assertEqual(queryset.count(), 1)
- data['form-0-uuid'] = 'INVALD_PRIMARY_KEY'
+ data["form-0-uuid"] = "INVALD_PRIMARY_KEY"
# The unfiltered queryset is returned if there's invalid data.
request = self.factory.post(changelist_url, data=data)
- queryset = m._get_list_editable_queryset(request, prefix='form')
+ queryset = m._get_list_editable_queryset(request, prefix="form")
self.assertEqual(queryset.count(), 2)
def test_get_list_editable_queryset_with_regex_chars_in_prefix(self):
- a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
- Swallow.objects.create(origin='Swallow B', load=2, speed=2)
+ a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)
+ Swallow.objects.create(origin="Swallow B", load=2, speed=2)
data = {
- 'form$-TOTAL_FORMS': '2',
- 'form$-INITIAL_FORMS': '2',
- 'form$-MIN_NUM_FORMS': '0',
- 'form$-MAX_NUM_FORMS': '1000',
- 'form$-0-uuid': str(a.pk),
- 'form$-0-load': '10',
- '_save': 'Save',
+ "form$-TOTAL_FORMS": "2",
+ "form$-INITIAL_FORMS": "2",
+ "form$-MIN_NUM_FORMS": "0",
+ "form$-MAX_NUM_FORMS": "1000",
+ "form$-0-uuid": str(a.pk),
+ "form$-0-load": "10",
+ "_save": "Save",
}
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
self.client.force_login(superuser)
- changelist_url = reverse('admin:admin_changelist_swallow_changelist')
+ changelist_url = reverse("admin:admin_changelist_swallow_changelist")
m = SwallowAdmin(Swallow, custom_site)
request = self.factory.post(changelist_url, data=data)
- queryset = m._get_list_editable_queryset(request, prefix='form$')
+ queryset = m._get_list_editable_queryset(request, prefix="form$")
self.assertEqual(queryset.count(), 1)
def test_changelist_view_list_editable_changed_objects_uses_filter(self):
"""list_editable edits use a filtered queryset to limit memory usage."""
- a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
- Swallow.objects.create(origin='Swallow B', load=2, speed=2)
+ a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)
+ Swallow.objects.create(origin="Swallow B", load=2, speed=2)
data = {
- 'form-TOTAL_FORMS': '2',
- 'form-INITIAL_FORMS': '2',
- 'form-MIN_NUM_FORMS': '0',
- 'form-MAX_NUM_FORMS': '1000',
- 'form-0-uuid': str(a.pk),
- 'form-0-load': '10',
- '_save': 'Save',
+ "form-TOTAL_FORMS": "2",
+ "form-INITIAL_FORMS": "2",
+ "form-MIN_NUM_FORMS": "0",
+ "form-MAX_NUM_FORMS": "1000",
+ "form-0-uuid": str(a.pk),
+ "form-0-load": "10",
+ "_save": "Save",
}
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
self.client.force_login(superuser)
- changelist_url = reverse('admin:admin_changelist_swallow_changelist')
+ changelist_url = reverse("admin:admin_changelist_swallow_changelist")
with CaptureQueriesContext(connection) as context:
response = self.client.post(changelist_url, data=data)
self.assertEqual(response.status_code, 200)
- self.assertIn('WHERE', context.captured_queries[4]['sql'])
- self.assertIn('IN', context.captured_queries[4]['sql'])
+ self.assertIn("WHERE", context.captured_queries[4]["sql"])
+ self.assertIn("IN", context.captured_queries[4]["sql"])
# Check only the first few characters since the UUID may have dashes.
- self.assertIn(str(a.pk)[:8], context.captured_queries[4]['sql'])
+ self.assertIn(str(a.pk)[:8], context.captured_queries[4]["sql"])
def test_deterministic_order_for_unordered_model(self):
"""
@@ -1096,7 +1175,7 @@ class ChangeListTests(TestCase):
guarantee a deterministic order, even when the model doesn't have any
default ordering defined (#17198).
"""
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
for counter in range(1, 51):
UnorderedObject.objects.create(id=counter, bool=True)
@@ -1109,9 +1188,11 @@ class ChangeListTests(TestCase):
model_admin = UnorderedObjectAdmin(UnorderedObject, custom_site)
counter = 0 if ascending else 51
for page in range(1, 6):
- request = self._mocked_authenticated_request('/unorderedobject/?p=%s' % page, superuser)
+ request = self._mocked_authenticated_request(
+ "/unorderedobject/?p=%s" % page, superuser
+ )
response = model_admin.changelist_view(request)
- for result in response.context_data['cl'].result_list:
+ for result in response.context_data["cl"].result_list:
counter += 1 if ascending else -1
self.assertEqual(result.id, counter)
custom_site.unregister(UnorderedObject)
@@ -1121,17 +1202,17 @@ class ChangeListTests(TestCase):
# When an order field is defined but multiple records have the same
# value for that field, make sure everything gets ordered by -pk as well.
- UnorderedObjectAdmin.ordering = ['bool']
+ UnorderedObjectAdmin.ordering = ["bool"]
check_results_order()
# When order fields are defined, including the pk itself, use them.
- UnorderedObjectAdmin.ordering = ['bool', '-pk']
+ UnorderedObjectAdmin.ordering = ["bool", "-pk"]
check_results_order()
- UnorderedObjectAdmin.ordering = ['bool', 'pk']
+ UnorderedObjectAdmin.ordering = ["bool", "pk"]
check_results_order(ascending=True)
- UnorderedObjectAdmin.ordering = ['-id', 'bool']
+ UnorderedObjectAdmin.ordering = ["-id", "bool"]
check_results_order()
- UnorderedObjectAdmin.ordering = ['id', 'bool']
+ UnorderedObjectAdmin.ordering = ["id", "bool"]
check_results_order(ascending=True)
def test_deterministic_order_for_model_ordered_by_its_manager(self):
@@ -1140,7 +1221,7 @@ class ChangeListTests(TestCase):
guarantee a deterministic order, even when the model has a manager that
defines a default ordering (#17198).
"""
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
for counter in range(1, 51):
OrderedObject.objects.create(id=counter, bool=True, number=counter)
@@ -1153,9 +1234,11 @@ class ChangeListTests(TestCase):
model_admin = OrderedObjectAdmin(OrderedObject, custom_site)
counter = 0 if ascending else 51
for page in range(1, 6):
- request = self._mocked_authenticated_request('/orderedobject/?p=%s' % page, superuser)
+ request = self._mocked_authenticated_request(
+ "/orderedobject/?p=%s" % page, superuser
+ )
response = model_admin.changelist_view(request)
- for result in response.context_data['cl'].result_list:
+ for result in response.context_data["cl"].result_list:
counter += 1 if ascending else -1
self.assertEqual(result.id, counter)
custom_site.unregister(OrderedObject)
@@ -1165,26 +1248,26 @@ class ChangeListTests(TestCase):
# When an order field is defined but multiple records have the same
# value for that field, make sure everything gets ordered by -pk as well.
- OrderedObjectAdmin.ordering = ['bool']
+ OrderedObjectAdmin.ordering = ["bool"]
check_results_order()
# When order fields are defined, including the pk itself, use them.
- OrderedObjectAdmin.ordering = ['bool', '-pk']
+ OrderedObjectAdmin.ordering = ["bool", "-pk"]
check_results_order()
- OrderedObjectAdmin.ordering = ['bool', 'pk']
+ OrderedObjectAdmin.ordering = ["bool", "pk"]
check_results_order(ascending=True)
- OrderedObjectAdmin.ordering = ['-id', 'bool']
+ OrderedObjectAdmin.ordering = ["-id", "bool"]
check_results_order()
- OrderedObjectAdmin.ordering = ['id', 'bool']
+ OrderedObjectAdmin.ordering = ["id", "bool"]
check_results_order(ascending=True)
- @isolate_apps('admin_changelist')
+ @isolate_apps("admin_changelist")
def test_total_ordering_optimization(self):
class Related(models.Model):
unique_field = models.BooleanField(unique=True)
class Meta:
- ordering = ('unique_field',)
+ ordering = ("unique_field",)
class Model(models.Model):
unique_field = models.BooleanField(unique=True)
@@ -1198,64 +1281,69 @@ class ChangeListTests(TestCase):
class Meta:
unique_together = {
- ('field', 'other_field'),
- ('field', 'null_field'),
- ('related', 'other_related_id'),
+ ("field", "other_field"),
+ ("field", "null_field"),
+ ("related", "other_related_id"),
}
class ModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
return Model.objects.none()
- request = self._mocked_authenticated_request('/', self.superuser)
- site = admin.AdminSite(name='admin')
+ request = self._mocked_authenticated_request("/", self.superuser)
+ site = admin.AdminSite(name="admin")
model_admin = ModelAdmin(Model, site)
change_list = model_admin.get_changelist_instance(request)
tests = (
- ([], ['-pk']),
+ ([], ["-pk"]),
# Unique non-nullable field.
- (['unique_field'], ['unique_field']),
- (['-unique_field'], ['-unique_field']),
+ (["unique_field"], ["unique_field"]),
+ (["-unique_field"], ["-unique_field"]),
# Unique nullable field.
- (['unique_nullable_field'], ['unique_nullable_field', '-pk']),
+ (["unique_nullable_field"], ["unique_nullable_field", "-pk"]),
# Field.
- (['field'], ['field', '-pk']),
+ (["field"], ["field", "-pk"]),
# Related field introspection is not implemented.
- (['related__unique_field'], ['related__unique_field', '-pk']),
+ (["related__unique_field"], ["related__unique_field", "-pk"]),
# Related attname unique.
- (['related_unique_id'], ['related_unique_id']),
+ (["related_unique_id"], ["related_unique_id"]),
# Related ordering introspection is not implemented.
- (['related_unique'], ['related_unique', '-pk']),
+ (["related_unique"], ["related_unique", "-pk"]),
# Composite unique.
- (['field', '-other_field'], ['field', '-other_field']),
+ (["field", "-other_field"], ["field", "-other_field"]),
# Composite unique nullable.
- (['-field', 'null_field'], ['-field', 'null_field', '-pk']),
+ (["-field", "null_field"], ["-field", "null_field", "-pk"]),
# Composite unique and nullable.
- (['-field', 'null_field', 'other_field'], ['-field', 'null_field', 'other_field']),
+ (
+ ["-field", "null_field", "other_field"],
+ ["-field", "null_field", "other_field"],
+ ),
# Composite unique attnames.
- (['related_id', '-other_related_id'], ['related_id', '-other_related_id']),
+ (["related_id", "-other_related_id"], ["related_id", "-other_related_id"]),
# Composite unique names.
- (['related', '-other_related_id'], ['related', '-other_related_id', '-pk']),
+ (["related", "-other_related_id"], ["related", "-other_related_id", "-pk"]),
)
# F() objects composite unique.
- total_ordering = [F('field'), F('other_field').desc(nulls_last=True)]
+ total_ordering = [F("field"), F("other_field").desc(nulls_last=True)]
# F() objects composite unique nullable.
- non_total_ordering = [F('field'), F('null_field').desc(nulls_last=True)]
+ non_total_ordering = [F("field"), F("null_field").desc(nulls_last=True)]
tests += (
(total_ordering, total_ordering),
- (non_total_ordering, non_total_ordering + ['-pk']),
+ (non_total_ordering, non_total_ordering + ["-pk"]),
)
for ordering, expected in tests:
with self.subTest(ordering=ordering):
- self.assertEqual(change_list._get_deterministic_ordering(ordering), expected)
+ self.assertEqual(
+ change_list._get_deterministic_ordering(ordering), expected
+ )
- @isolate_apps('admin_changelist')
+ @isolate_apps("admin_changelist")
def test_total_ordering_optimization_meta_constraints(self):
class Related(models.Model):
unique_field = models.BooleanField(unique=True)
class Meta:
- ordering = ('unique_field',)
+ ordering = ("unique_field",)
class Model(models.Model):
field_1 = models.BooleanField()
@@ -1274,28 +1362,28 @@ class ChangeListTests(TestCase):
class Meta:
constraints = [
*[
- models.UniqueConstraint(fields=fields, name=''.join(fields))
+ models.UniqueConstraint(fields=fields, name="".join(fields))
for fields in (
- ['field_1'],
- ['nullable_1'],
- ['related_1'],
- ['related_2_id'],
- ['field_2', 'field_3'],
- ['field_2', 'nullable_2'],
- ['field_2', 'related_3'],
- ['field_3', 'related_4_id'],
+ ["field_1"],
+ ["nullable_1"],
+ ["related_1"],
+ ["related_2_id"],
+ ["field_2", "field_3"],
+ ["field_2", "nullable_2"],
+ ["field_2", "related_3"],
+ ["field_3", "related_4_id"],
)
],
- models.CheckConstraint(check=models.Q(id__gt=0), name='foo'),
+ models.CheckConstraint(check=models.Q(id__gt=0), name="foo"),
models.UniqueConstraint(
- fields=['field_5'],
+ fields=["field_5"],
condition=models.Q(id__gt=10),
- name='total_ordering_1',
+ name="total_ordering_1",
),
models.UniqueConstraint(
- fields=['field_6'],
+ fields=["field_6"],
condition=models.Q(),
- name='total_ordering',
+ name="total_ordering",
),
]
@@ -1303,73 +1391,77 @@ class ChangeListTests(TestCase):
def get_queryset(self, request):
return Model.objects.none()
- request = self._mocked_authenticated_request('/', self.superuser)
- site = admin.AdminSite(name='admin')
+ request = self._mocked_authenticated_request("/", self.superuser)
+ site = admin.AdminSite(name="admin")
model_admin = ModelAdmin(Model, site)
change_list = model_admin.get_changelist_instance(request)
tests = (
# Unique non-nullable field.
- (['field_1'], ['field_1']),
+ (["field_1"], ["field_1"]),
# Unique nullable field.
- (['nullable_1'], ['nullable_1', '-pk']),
+ (["nullable_1"], ["nullable_1", "-pk"]),
# Related attname unique.
- (['related_1_id'], ['related_1_id']),
- (['related_2_id'], ['related_2_id']),
+ (["related_1_id"], ["related_1_id"]),
+ (["related_2_id"], ["related_2_id"]),
# Related ordering introspection is not implemented.
- (['related_1'], ['related_1', '-pk']),
+ (["related_1"], ["related_1", "-pk"]),
# Composite unique.
- (['-field_2', 'field_3'], ['-field_2', 'field_3']),
+ (["-field_2", "field_3"], ["-field_2", "field_3"]),
# Composite unique nullable.
- (['field_2', '-nullable_2'], ['field_2', '-nullable_2', '-pk']),
+ (["field_2", "-nullable_2"], ["field_2", "-nullable_2", "-pk"]),
# Composite unique and nullable.
(
- ['field_2', '-nullable_2', 'field_3'],
- ['field_2', '-nullable_2', 'field_3'],
+ ["field_2", "-nullable_2", "field_3"],
+ ["field_2", "-nullable_2", "field_3"],
),
# Composite field and related field name.
- (['field_2', '-related_3'], ['field_2', '-related_3', '-pk']),
- (['field_3', 'related_4'], ['field_3', 'related_4', '-pk']),
+ (["field_2", "-related_3"], ["field_2", "-related_3", "-pk"]),
+ (["field_3", "related_4"], ["field_3", "related_4", "-pk"]),
# Composite field and related field attname.
- (['field_2', 'related_3_id'], ['field_2', 'related_3_id']),
- (['field_3', '-related_4_id'], ['field_3', '-related_4_id']),
+ (["field_2", "related_3_id"], ["field_2", "related_3_id"]),
+ (["field_3", "-related_4_id"], ["field_3", "-related_4_id"]),
# Partial unique constraint is ignored.
- (['field_5'], ['field_5', '-pk']),
+ (["field_5"], ["field_5", "-pk"]),
# Unique constraint with an empty condition.
- (['field_6'], ['field_6']),
+ (["field_6"], ["field_6"]),
)
for ordering, expected in tests:
with self.subTest(ordering=ordering):
- self.assertEqual(change_list._get_deterministic_ordering(ordering), expected)
+ self.assertEqual(
+ change_list._get_deterministic_ordering(ordering), expected
+ )
def test_dynamic_list_filter(self):
"""
Regression tests for ticket #17646: dynamic list_filter support.
"""
- parent = Parent.objects.create(name='parent')
+ parent = Parent.objects.create(name="parent")
for i in range(10):
- Child.objects.create(name='child %s' % i, parent=parent)
+ Child.objects.create(name="child %s" % i, parent=parent)
- user_noparents = self._create_superuser('noparents')
- user_parents = self._create_superuser('parents')
+ user_noparents = self._create_superuser("noparents")
+ user_parents = self._create_superuser("parents")
# Test with user 'noparents'
m = DynamicListFilterChildAdmin(Child, custom_site)
- request = self._mocked_authenticated_request('/child/', user_noparents)
+ request = self._mocked_authenticated_request("/child/", user_noparents)
response = m.changelist_view(request)
- self.assertEqual(response.context_data['cl'].list_filter, ['name', 'age'])
+ self.assertEqual(response.context_data["cl"].list_filter, ["name", "age"])
# Test with user 'parents'
m = DynamicListFilterChildAdmin(Child, custom_site)
- request = self._mocked_authenticated_request('/child/', user_parents)
+ request = self._mocked_authenticated_request("/child/", user_parents)
response = m.changelist_view(request)
- self.assertEqual(response.context_data['cl'].list_filter, ('parent', 'name', 'age'))
+ self.assertEqual(
+ response.context_data["cl"].list_filter, ("parent", "name", "age")
+ )
def test_dynamic_search_fields(self):
- child = self._create_superuser('child')
+ child = self._create_superuser("child")
m = DynamicSearchFieldsChildAdmin(Child, custom_site)
- request = self._mocked_authenticated_request('/child/', child)
+ request = self._mocked_authenticated_request("/child/", child)
response = m.changelist_view(request)
- self.assertEqual(response.context_data['cl'].search_fields, ('name', 'age'))
+ self.assertEqual(response.context_data["cl"].search_fields, ("name", "age"))
def test_pagination_page_range(self):
"""
@@ -1378,7 +1470,7 @@ class ChangeListTests(TestCase):
"""
# instantiating and setting up ChangeList object
m = GroupAdmin(Group, custom_site)
- request = self.factory.get('/group/')
+ request = self.factory.get("/group/")
request.user = self.superuser
cl = m.get_changelist_instance(request)
cl.list_per_page = 10
@@ -1401,144 +1493,148 @@ class ChangeListTests(TestCase):
# assuming exactly `pages * cl.list_per_page` objects
Group.objects.all().delete()
for i in range(pages * cl.list_per_page):
- Group.objects.create(name='test band')
+ Group.objects.create(name="test band")
# setting page number and calculating page range
cl.page_num = number
cl.get_results(request)
- self.assertEqual(list(pagination(cl)['page_range']), expected)
+ self.assertEqual(list(pagination(cl)["page_range"]), expected)
def test_object_tools_displayed_no_add_permission(self):
"""
When ModelAdmin.has_add_permission() returns False, the object-tools
block is still shown.
"""
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
m = EventAdmin(Event, custom_site)
- request = self._mocked_authenticated_request('/event/', superuser)
+ request = self._mocked_authenticated_request("/event/", superuser)
self.assertFalse(m.has_add_permission(request))
response = m.changelist_view(request)
self.assertIn('<ul class="object-tools">', response.rendered_content)
# The "Add" button inside the object-tools shouldn't appear.
- self.assertNotIn('Add ', response.rendered_content)
+ self.assertNotIn("Add ", response.rendered_content)
def test_search_help_text(self):
- superuser = self._create_superuser('superuser')
+ superuser = self._create_superuser("superuser")
m = BandAdmin(Band, custom_site)
# search_fields without search_help_text.
- m.search_fields = ['name']
- request = self._mocked_authenticated_request('/band/', superuser)
+ m.search_fields = ["name"]
+ request = self._mocked_authenticated_request("/band/", superuser)
response = m.changelist_view(request)
- self.assertIsNone(response.context_data['cl'].search_help_text)
+ self.assertIsNone(response.context_data["cl"].search_help_text)
self.assertNotContains(response, '<div class="help">')
# search_fields with search_help_text.
- m.search_help_text = 'Search help text'
- request = self._mocked_authenticated_request('/band/', superuser)
+ m.search_help_text = "Search help text"
+ request = self._mocked_authenticated_request("/band/", superuser)
response = m.changelist_view(request)
- self.assertEqual(response.context_data['cl'].search_help_text, 'Search help text')
+ self.assertEqual(
+ response.context_data["cl"].search_help_text, "Search help text"
+ )
self.assertContains(response, '<div class="help">Search help text</div>')
class GetAdminLogTests(TestCase):
-
def test_custom_user_pk_not_named_id(self):
"""
{% get_admin_log %} works if the user model's primary key isn't named
'id'.
"""
- context = Context({'user': CustomIdUser()})
- template = Template('{% load log %}{% get_admin_log 10 as admin_log for_user user %}')
+ context = Context({"user": CustomIdUser()})
+ template = Template(
+ "{% load log %}{% get_admin_log 10 as admin_log for_user user %}"
+ )
# This template tag just logs.
- self.assertEqual(template.render(context), '')
+ self.assertEqual(template.render(context), "")
def test_no_user(self):
"""{% get_admin_log %} works without specifying a user."""
- user = User(username='jondoe', password='secret', email='super@example.com')
+ user = User(username="jondoe", password="secret", email="super@example.com")
user.save()
ct = ContentType.objects.get_for_model(User)
LogEntry.objects.log_action(user.pk, ct.pk, user.pk, repr(user), 1)
t = Template(
- '{% load log %}'
- '{% get_admin_log 100 as admin_log %}'
- '{% for entry in admin_log %}'
- '{{ entry|safe }}'
- '{% endfor %}'
+ "{% load log %}"
+ "{% get_admin_log 100 as admin_log %}"
+ "{% for entry in admin_log %}"
+ "{{ entry|safe }}"
+ "{% endfor %}"
)
- self.assertEqual(t.render(Context({})), 'Added “<User: jondoe>”.')
+ self.assertEqual(t.render(Context({})), "Added “<User: jondoe>”.")
def test_missing_args(self):
msg = "'get_admin_log' statements require two arguments"
with self.assertRaisesMessage(TemplateSyntaxError, msg):
- Template('{% load log %}{% get_admin_log 10 as %}')
+ Template("{% load log %}{% get_admin_log 10 as %}")
def test_non_integer_limit(self):
msg = "First argument to 'get_admin_log' must be an integer"
with self.assertRaisesMessage(TemplateSyntaxError, msg):
- Template('{% load log %}{% get_admin_log "10" as admin_log for_user user %}')
+ Template(
+ '{% load log %}{% get_admin_log "10" as admin_log for_user user %}'
+ )
def test_without_as(self):
msg = "Second argument to 'get_admin_log' must be 'as'"
with self.assertRaisesMessage(TemplateSyntaxError, msg):
- Template('{% load log %}{% get_admin_log 10 ad admin_log for_user user %}')
+ Template("{% load log %}{% get_admin_log 10 ad admin_log for_user user %}")
def test_without_for_user(self):
msg = "Fourth argument to 'get_admin_log' must be 'for_user'"
with self.assertRaisesMessage(TemplateSyntaxError, msg):
- Template('{% load log %}{% get_admin_log 10 as admin_log foruser user %}')
+ Template("{% load log %}{% get_admin_log 10 as admin_log foruser user %}")
-@override_settings(ROOT_URLCONF='admin_changelist.urls')
+@override_settings(ROOT_URLCONF="admin_changelist.urls")
class SeleniumTests(AdminSeleniumTestCase):
- available_apps = ['admin_changelist'] + AdminSeleniumTestCase.available_apps
+ available_apps = ["admin_changelist"] + AdminSeleniumTestCase.available_apps
def setUp(self):
- User.objects.create_superuser(username='super', password='secret', email=None)
+ User.objects.create_superuser(username="super", password="secret", email=None)
def test_add_row_selection(self):
"""
The status line for selected rows gets updated correctly (#22038).
"""
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret')
- self.selenium.get(self.live_server_url + reverse('admin:auth_user_changelist'))
- form_id = '#changelist-form'
+ self.admin_login(username="super", password="secret")
+ self.selenium.get(self.live_server_url + reverse("admin:auth_user_changelist"))
+
+ form_id = "#changelist-form"
# Test amount of rows in the Changelist
rows = self.selenium.find_elements(
- By.CSS_SELECTOR,
- '%s #result_list tbody tr' % form_id
+ By.CSS_SELECTOR, "%s #result_list tbody tr" % form_id
)
self.assertEqual(len(rows), 1)
row = rows[0]
selection_indicator = self.selenium.find_element(
- By.CSS_SELECTOR,
- '%s .action-counter' % form_id
+ By.CSS_SELECTOR, "%s .action-counter" % form_id
)
- all_selector = self.selenium.find_element(By.ID, 'action-toggle')
+ all_selector = self.selenium.find_element(By.ID, "action-toggle")
row_selector = self.selenium.find_element(
By.CSS_SELECTOR,
- '%s #result_list tbody tr:first-child .action-select' % form_id
+ "%s #result_list tbody tr:first-child .action-select" % form_id,
)
# Test current selection
self.assertEqual(selection_indicator.text, "0 of 1 selected")
- self.assertIs(all_selector.get_property('checked'), False)
- self.assertEqual(row.get_attribute('class'), '')
+ self.assertIs(all_selector.get_property("checked"), False)
+ self.assertEqual(row.get_attribute("class"), "")
# Select a row and check again
row_selector.click()
self.assertEqual(selection_indicator.text, "1 of 1 selected")
- self.assertIs(all_selector.get_property('checked'), True)
- self.assertEqual(row.get_attribute('class'), 'selected')
+ self.assertIs(all_selector.get_property("checked"), True)
+ self.assertEqual(row.get_attribute("class"), "selected")
# Deselect a row and check again
row_selector.click()
self.assertEqual(selection_indicator.text, "0 of 1 selected")
- self.assertIs(all_selector.get_property('checked'), False)
- self.assertEqual(row.get_attribute('class'), '')
+ self.assertIs(all_selector.get_property("checked"), False)
+ self.assertEqual(row.get_attribute("class"), "")
def test_modifier_allows_multiple_section(self):
"""
@@ -1549,89 +1645,105 @@ class SeleniumTests(AdminSeleniumTestCase):
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
- Parent.objects.bulk_create([Parent(name='parent%d' % i) for i in range(5)])
- self.admin_login(username='super', password='secret')
- self.selenium.get(self.live_server_url + reverse('admin:admin_changelist_parent_changelist'))
- checkboxes = self.selenium.find_elements(By.CSS_SELECTOR, 'tr input.action-select')
+ Parent.objects.bulk_create([Parent(name="parent%d" % i) for i in range(5)])
+ self.admin_login(username="super", password="secret")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_changelist_parent_changelist")
+ )
+ checkboxes = self.selenium.find_elements(
+ By.CSS_SELECTOR, "tr input.action-select"
+ )
self.assertEqual(len(checkboxes), 5)
for c in checkboxes:
- self.assertIs(c.get_property('checked'), False)
+ self.assertIs(c.get_property("checked"), False)
# Check first row. Hold-shift and check next-to-last row.
checkboxes[0].click()
- ActionChains(self.selenium).key_down(Keys.SHIFT).click(checkboxes[-2]).key_up(Keys.SHIFT).perform()
+ ActionChains(self.selenium).key_down(Keys.SHIFT).click(checkboxes[-2]).key_up(
+ Keys.SHIFT
+ ).perform()
for c in checkboxes[:-2]:
- self.assertIs(c.get_property('checked'), True)
- self.assertIs(checkboxes[-1].get_property('checked'), False)
+ self.assertIs(c.get_property("checked"), True)
+ self.assertIs(checkboxes[-1].get_property("checked"), False)
def test_select_all_across_pages(self):
from selenium.webdriver.common.by import By
- Parent.objects.bulk_create([Parent(name='parent%d' % i) for i in range(101)])
- self.admin_login(username='super', password='secret')
- self.selenium.get(self.live_server_url + reverse('admin:admin_changelist_parent_changelist'))
- selection_indicator = self.selenium.find_element(By.CSS_SELECTOR, '.action-counter')
- select_all_indicator = self.selenium.find_element(By.CSS_SELECTOR, '.actions .all')
- question = self.selenium.find_element(By.CSS_SELECTOR, '.actions > .question')
- clear = self.selenium.find_element(By.CSS_SELECTOR, '.actions > .clear')
- select_all = self.selenium.find_element(By.ID, 'action-toggle')
- select_across = self.selenium.find_elements(By.NAME, 'select_across')
+ Parent.objects.bulk_create([Parent(name="parent%d" % i) for i in range(101)])
+ self.admin_login(username="super", password="secret")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_changelist_parent_changelist")
+ )
+
+ selection_indicator = self.selenium.find_element(
+ By.CSS_SELECTOR, ".action-counter"
+ )
+ select_all_indicator = self.selenium.find_element(
+ By.CSS_SELECTOR, ".actions .all"
+ )
+ question = self.selenium.find_element(By.CSS_SELECTOR, ".actions > .question")
+ clear = self.selenium.find_element(By.CSS_SELECTOR, ".actions > .clear")
+ select_all = self.selenium.find_element(By.ID, "action-toggle")
+ select_across = self.selenium.find_elements(By.NAME, "select_across")
self.assertIs(question.is_displayed(), False)
self.assertIs(clear.is_displayed(), False)
- self.assertIs(select_all.get_property('checked'), False)
+ self.assertIs(select_all.get_property("checked"), False)
for hidden_input in select_across:
- self.assertEqual(hidden_input.get_property('value'), '0')
+ self.assertEqual(hidden_input.get_property("value"), "0")
self.assertIs(selection_indicator.is_displayed(), True)
- self.assertEqual(selection_indicator.text, '0 of 100 selected')
+ self.assertEqual(selection_indicator.text, "0 of 100 selected")
self.assertIs(select_all_indicator.is_displayed(), False)
select_all.click()
self.assertIs(question.is_displayed(), True)
self.assertIs(clear.is_displayed(), False)
- self.assertIs(select_all.get_property('checked'), True)
+ self.assertIs(select_all.get_property("checked"), True)
for hidden_input in select_across:
- self.assertEqual(hidden_input.get_property('value'), '0')
+ self.assertEqual(hidden_input.get_property("value"), "0")
self.assertIs(selection_indicator.is_displayed(), True)
- self.assertEqual(selection_indicator.text, '100 of 100 selected')
+ self.assertEqual(selection_indicator.text, "100 of 100 selected")
self.assertIs(select_all_indicator.is_displayed(), False)
question.click()
self.assertIs(question.is_displayed(), False)
self.assertIs(clear.is_displayed(), True)
- self.assertIs(select_all.get_property('checked'), True)
+ self.assertIs(select_all.get_property("checked"), True)
for hidden_input in select_across:
- self.assertEqual(hidden_input.get_property('value'), '1')
+ self.assertEqual(hidden_input.get_property("value"), "1")
self.assertIs(selection_indicator.is_displayed(), False)
self.assertIs(select_all_indicator.is_displayed(), True)
clear.click()
self.assertIs(question.is_displayed(), False)
self.assertIs(clear.is_displayed(), False)
- self.assertIs(select_all.get_property('checked'), False)
+ self.assertIs(select_all.get_property("checked"), False)
for hidden_input in select_across:
- self.assertEqual(hidden_input.get_property('value'), '0')
+ self.assertEqual(hidden_input.get_property("value"), "0")
self.assertIs(selection_indicator.is_displayed(), True)
- self.assertEqual(selection_indicator.text, '0 of 100 selected')
+ self.assertEqual(selection_indicator.text, "0 of 100 selected")
self.assertIs(select_all_indicator.is_displayed(), False)
def test_actions_warn_on_pending_edits(self):
from selenium.webdriver.common.by import By
- Parent.objects.create(name='foo')
- self.admin_login(username='super', password='secret')
- self.selenium.get(self.live_server_url + reverse('admin:admin_changelist_parent_changelist'))
+ Parent.objects.create(name="foo")
- name_input = self.selenium.find_element(By.ID, 'id_form-0-name')
+ self.admin_login(username="super", password="secret")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_changelist_parent_changelist")
+ )
+
+ name_input = self.selenium.find_element(By.ID, "id_form-0-name")
name_input.clear()
- name_input.send_keys('bar')
- self.selenium.find_element(By.ID, 'action-toggle').click()
- self.selenium.find_element(By.NAME, 'index').click() # Go
+ name_input.send_keys("bar")
+ self.selenium.find_element(By.ID, "action-toggle").click()
+ self.selenium.find_element(By.NAME, "index").click() # Go
alert = self.selenium.switch_to.alert
try:
self.assertEqual(
alert.text,
- 'You have unsaved changes on individual editable fields. If you '
- 'run an action, your unsaved changes will be lost.'
+ "You have unsaved changes on individual editable fields. If you "
+ "run an action, your unsaved changes will be lost.",
)
finally:
alert.dismiss()
@@ -1640,25 +1752,27 @@ class SeleniumTests(AdminSeleniumTestCase):
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
- Parent.objects.create(name='parent')
+ Parent.objects.create(name="parent")
- self.admin_login(username='super', password='secret')
- self.selenium.get(self.live_server_url + reverse('admin:admin_changelist_parent_changelist'))
+ self.admin_login(username="super", password="secret")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_changelist_parent_changelist")
+ )
- name_input = self.selenium.find_element(By.ID, 'id_form-0-name')
+ name_input = self.selenium.find_element(By.ID, "id_form-0-name")
name_input.clear()
- name_input.send_keys('other name')
- Select(
- self.selenium.find_element(By.NAME, 'action')
- ).select_by_value('delete_selected')
- self.selenium.find_element(By.NAME, '_save').click()
+ name_input.send_keys("other name")
+ Select(self.selenium.find_element(By.NAME, "action")).select_by_value(
+ "delete_selected"
+ )
+ self.selenium.find_element(By.NAME, "_save").click()
alert = self.selenium.switch_to.alert
try:
self.assertEqual(
alert.text,
- 'You have selected an action, but you haven’t saved your '
- 'changes to individual fields yet. Please click OK to save. '
- 'You’ll need to re-run the action.',
+ "You have selected an action, but you haven’t saved your "
+ "changes to individual fields yet. Please click OK to save. "
+ "You’ll need to re-run the action.",
)
finally:
alert.dismiss()
@@ -1667,22 +1781,24 @@ class SeleniumTests(AdminSeleniumTestCase):
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
- Parent.objects.create(name='parent')
+ Parent.objects.create(name="parent")
- self.admin_login(username='super', password='secret')
- self.selenium.get(self.live_server_url + reverse('admin:admin_changelist_parent_changelist'))
+ self.admin_login(username="super", password="secret")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_changelist_parent_changelist")
+ )
- Select(
- self.selenium.find_element(By.NAME, 'action')
- ).select_by_value('delete_selected')
- self.selenium.find_element(By.NAME, '_save').click()
+ Select(self.selenium.find_element(By.NAME, "action")).select_by_value(
+ "delete_selected"
+ )
+ self.selenium.find_element(By.NAME, "_save").click()
alert = self.selenium.switch_to.alert
try:
self.assertEqual(
alert.text,
- 'You have selected an action, and you haven’t made any '
- 'changes on individual fields. You’re probably looking for '
- 'the Go button rather than the Save button.',
+ "You have selected an action, and you haven’t made any "
+ "changes on individual fields. You’re probably looking for "
+ "the Go button rather than the Save button.",
)
finally:
alert.dismiss()
diff --git a/tests/admin_changelist/urls.py b/tests/admin_changelist/urls.py
index be569cdca5..ad9b44c9fc 100644
--- a/tests/admin_changelist/urls.py
+++ b/tests/admin_changelist/urls.py
@@ -3,5 +3,5 @@ from django.urls import path
from . import admin
urlpatterns = [
- path('admin/', admin.site.urls),
+ path("admin/", admin.site.urls),
]