diff options
| author | Adam Donaghy <adamdonaghy1994@gmail.com> | 2018-05-03 23:41:04 +1000 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-06-01 11:00:34 -0400 |
| commit | 22c7c2db1dcc3d0ba2799441e7de025d502b3a4c (patch) | |
| tree | e03e5e89e383d695ea0bef8e1db5d967ae76a324 /django/contrib/admin/options.py | |
| parent | b935f112e1a3db6919c9c7ad873e1451c79e31fe (diff) | |
[2.0.x] Fixed #28462 -- Decreased memory usage with ModelAdmin.list_editable.
Regression in 917cc288a38f3c114a5440f0749b7e5e1086eb36.
Backport of b18650a2634890aa758abae2f33875daa13a9ba3 from master
Diffstat (limited to 'django/contrib/admin/options.py')
| -rw-r--r-- | django/contrib/admin/options.py | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 1eee19fea4..8d8f263db1 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 @@ -1555,6 +1556,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): """ @@ -1629,7 +1651,8 @@ class ModelAdmin(BaseModelAdmin): # Handle POSTed bulk-edit data. if request.method == 'POST' and cl.list_editable and '_save' in request.POST: 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: |
