summaryrefslogtreecommitdiff
path: root/django
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 /django
parente1ebd22558342bb0088a3da3571863a20413fa2a (diff)
Fixed #28462 -- Decreased memory usage with ModelAdmin.list_editable.
Regression in 917cc288a38f3c114a5440f0749b7e5e1086eb36.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/options.py25
1 files changed, 24 insertions, 1 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 5b7de20e2d..206e01a2f0 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -1,6 +1,7 @@
import copy
import json
import operator
+import re
from collections import OrderedDict
from functools import partial, reduce, update_wrapper
from urllib.parse import quote as urlquote
@@ -1633,6 +1634,27 @@ class ModelAdmin(BaseModelAdmin):
def change_view(self, request, object_id, form_url='', extra_context=None):
return self.changeform_view(request, object_id, form_url, extra_context)
+ def _get_edited_object_pks(self, request, prefix):
+ """Return POST data values of list_editable primary keys."""
+ pk_pattern = re.compile('{}-\d+-{}$'.format(prefix, self.model._meta.pk.name))
+ return [value for key, value in request.POST.items() if pk_pattern.match(key)]
+
+ def _get_list_editable_queryset(self, request, prefix):
+ """
+ Based on POST data, return a queryset of the objects that were edited
+ via list_editable.
+ """
+ object_pks = self._get_edited_object_pks(request, prefix)
+ queryset = self.get_queryset(request)
+ validate = queryset.model._meta.pk.to_python
+ try:
+ for pk in object_pks:
+ validate(pk)
+ except ValidationError:
+ # Disable the optimization if the POST data was tampered with.
+ return queryset
+ return queryset.filter(pk__in=object_pks)
+
@csrf_protect_m
def changelist_view(self, request, extra_context=None):
"""
@@ -1713,7 +1735,8 @@ class ModelAdmin(BaseModelAdmin):
if not self.has_change_permission(request):
raise PermissionDenied
FormSet = self.get_changelist_formset(request)
- formset = cl.formset = FormSet(request.POST, request.FILES, queryset=self.get_queryset(request))
+ modified_objects = self._get_list_editable_queryset(request, FormSet.get_default_prefix())
+ formset = cl.formset = FormSet(request.POST, request.FILES, queryset=modified_objects)
if formset.is_valid():
changecount = 0
for form in formset.forms: