diff options
| author | Adam Donaghy <adamdonaghy1994@gmail.com> | 2018-05-03 23:41:04 +1000 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-06-01 10:41:05 -0400 |
| commit | b18650a2634890aa758abae2f33875daa13a9ba3 (patch) | |
| tree | e614f32f63338aec5d913f33f76ef3786cac458c /django | |
| parent | e1ebd22558342bb0088a3da3571863a20413fa2a (diff) | |
Fixed #28462 -- Decreased memory usage with ModelAdmin.list_editable.
Regression in 917cc288a38f3c114a5440f0749b7e5e1086eb36.
Diffstat (limited to 'django')
| -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 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: |
