[2.2.x] Fixed #31031 -- Fixed data loss in admin changelist view when formset's prefix contains regex special chars.
Regression inb18650a263
. Backport of52936eface
from master
This commit is contained in:
parent
2af606003a
commit
7873d3757d
|
@ -1638,7 +1638,9 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def _get_edited_object_pks(self, request, prefix):
|
def _get_edited_object_pks(self, request, prefix):
|
||||||
"""Return POST data values of list_editable primary keys."""
|
"""Return POST data values of list_editable primary keys."""
|
||||||
pk_pattern = re.compile(r'{}-\d+-{}$'.format(prefix, self.model._meta.pk.name))
|
pk_pattern = re.compile(
|
||||||
|
r'{}-\d+-{}$'.format(re.escape(prefix), self.model._meta.pk.name)
|
||||||
|
)
|
||||||
return [value for key, value in request.POST.items() if pk_pattern.match(key)]
|
return [value for key, value in request.POST.items() if pk_pattern.match(key)]
|
||||||
|
|
||||||
def _get_list_editable_queryset(self, request, prefix):
|
def _get_list_editable_queryset(self, request, prefix):
|
||||||
|
|
|
@ -10,4 +10,6 @@ Django 2.2.8 fixes several bugs in 2.2.7 and adds compatibility with Python
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed a data loss possibility in the admin changelist view when a custom
|
||||||
|
:ref:`formset's prefix <formset-prefix>` contains regular expression special
|
||||||
|
characters, e.g. `'$'` (:ticket:`31031`).
|
||||||
|
|
|
@ -827,6 +827,26 @@ class ChangeListTests(TestCase):
|
||||||
queryset = m._get_list_editable_queryset(request, prefix='form')
|
queryset = m._get_list_editable_queryset(request, prefix='form')
|
||||||
self.assertEqual(queryset.count(), 2)
|
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)
|
||||||
|
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)
|
||||||
|
|
||||||
def test_changelist_view_list_editable_changed_objects_uses_filter(self):
|
def test_changelist_view_list_editable_changed_objects_uses_filter(self):
|
||||||
"""list_editable edits use a filtered queryset to limit memory usage."""
|
"""list_editable edits use a filtered queryset to limit memory usage."""
|
||||||
a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
|
a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
|
||||||
|
|
Loading…
Reference in New Issue