summaryrefslogtreecommitdiff
path: root/tests/admin_changelist
diff options
context:
space:
mode:
authorAdam Donaghy <adamdonaghy1994@gmail.com>2018-05-03 23:41:04 +1000
committerTim Graham <timograham@gmail.com>2018-06-01 10:41:05 -0400
commitb18650a2634890aa758abae2f33875daa13a9ba3 (patch)
treee614f32f63338aec5d913f33f76ef3786cac458c /tests/admin_changelist
parente1ebd22558342bb0088a3da3571863a20413fa2a (diff)
downloaddjango-b18650a2634890aa758abae2f33875daa13a9ba3.tar.gz
Fixed #28462 -- Decreased memory usage with ModelAdmin.list_editable.
Regression in 917cc288a38f3c114a5440f0749b7e5e1086eb36.
Diffstat (limited to 'tests/admin_changelist')
-rw-r--r--tests/admin_changelist/models.py3
-rw-r--r--tests/admin_changelist/tests.py85
2 files changed, 85 insertions, 3 deletions
diff --git a/tests/admin_changelist/models.py b/tests/admin_changelist/models.py
index 62268a2b79..81d7fdfb3a 100644
--- a/tests/admin_changelist/models.py
+++ b/tests/admin_changelist/models.py
@@ -1,3 +1,5 @@
+import uuid
+
from django.db import models
@@ -73,6 +75,7 @@ class Invitation(models.Model):
class Swallow(models.Model):
+ uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
origin = models.CharField(max_length=255)
load = models.FloatField()
speed = models.FloatField()
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index 20587613a7..9f9150f34d 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -8,6 +8,7 @@ from django.contrib.admin.tests import AdminSeleniumTestCase
from django.contrib.admin.views.main import ALL_VAR, SEARCH_VAR
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
+from django.db import connection
from django.db.models import F
from django.db.models.fields import Field, IntegerField
from django.db.models.functions import Upper
@@ -15,6 +16,7 @@ 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
from django.urls import reverse
from django.utils import formats
@@ -732,9 +734,9 @@ class ChangeListTests(TestCase):
'form-INITIAL_FORMS': '3',
'form-MIN_NUM_FORMS': '0',
'form-MAX_NUM_FORMS': '1000',
- 'form-0-id': str(d.pk),
- 'form-1-id': str(c.pk),
- 'form-2-id': str(a.pk),
+ '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',
@@ -764,6 +766,83 @@ class ChangeListTests(TestCase):
# 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')
+ self.client.force_login(superuser)
+ 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',
+ }
+ request = self.factory.post(changelist_url, data=data)
+ 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)
+ 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',
+ }
+ superuser = self._create_superuser('superuser')
+ self.client.force_login(superuser)
+ 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')
+ self.assertEqual(queryset.count(), 1)
+ 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')
+ self.assertEqual(queryset.count(), 2)
+
+ 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)
+ 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',
+ }
+ superuser = self._create_superuser('superuser')
+ self.client.force_login(superuser)
+ 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'])
+ # Check only the first few characters since the UUID may have dashes.
+ self.assertIn(str(a.pk)[:8], context.captured_queries[4]['sql'])
+
def test_deterministic_order_for_unordered_model(self):
"""
The primary key is used in the ordering of the changelist's results to