[3.0.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
b3ffa0d51d
commit
3ed55606c4
|
@ -1631,7 +1631,9 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
def _get_edited_object_pks(self, request, prefix):
|
||||
"""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)]
|
||||
|
||||
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
|
||||
========
|
||||
|
||||
* ...
|
||||
* 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`).
|
||||
|
|
|
@ -844,6 +844,26 @@ class ChangeListTests(TestCase):
|
|||
queryset = m._get_list_editable_queryset(request, prefix='form')
|
||||
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):
|
||||
"""list_editable edits use a filtered queryset to limit memory usage."""
|
||||
a = Swallow.objects.create(origin='Swallow A', load=4, speed=1)
|
||||
|
|
Loading…
Reference in New Issue