[2.1.x] Fixed #30050 -- Fixed InlineModelAdmin.has_change_permission() called with non-None obj during add.
Thanks andreage for the report and suggested fix.
Backport of 02c07be95c
from master.
This commit is contained in:
parent
65ccb1b7e4
commit
4e4b952123
|
@ -1959,7 +1959,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
# Bypass validation of each view-only inline form (since the form's
|
# Bypass validation of each view-only inline form (since the form's
|
||||||
# data won't be in request.POST), unless the form was deleted.
|
# data won't be in request.POST), unless the form was deleted.
|
||||||
if not inline.has_change_permission(request, obj):
|
if not inline.has_change_permission(request, obj if change else None):
|
||||||
for index, form in enumerate(formset.initial_forms):
|
for index, form in enumerate(formset.initial_forms):
|
||||||
if user_deleted_form(request, obj, formset, index):
|
if user_deleted_form(request, obj, formset, index):
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -22,3 +22,7 @@ Bugfixes
|
||||||
* Fixed a regression in Django 2.1.4 (which enabled keep-alive connections)
|
* Fixed a regression in Django 2.1.4 (which enabled keep-alive connections)
|
||||||
where request body data isn't properly consumed for such connections
|
where request body data isn't properly consumed for such connections
|
||||||
(:ticket:`30015`).
|
(:ticket:`30015`).
|
||||||
|
|
||||||
|
* Fixed a regression in Django 2.1.4 where
|
||||||
|
``InlineModelAdmin.has_change_permission()`` is incorrectly called with a
|
||||||
|
non-``None`` ``obj`` argument during an object add (:ticket:`30050`).
|
||||||
|
|
|
@ -2,6 +2,7 @@ import datetime
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import unittest
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
from urllib.parse import parse_qsl, urljoin, urlparse
|
from urllib.parse import parse_qsl, urljoin, urlparse
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
@ -1740,6 +1741,24 @@ class AdminViewPermissionsTest(TestCase):
|
||||||
# make sure the view removes test cookie
|
# make sure the view removes test cookie
|
||||||
self.assertIs(self.client.session.test_cookie_worked(), False)
|
self.assertIs(self.client.session.test_cookie_worked(), False)
|
||||||
|
|
||||||
|
@mock.patch('django.contrib.admin.options.InlineModelAdmin.has_change_permission')
|
||||||
|
def test_add_view_with_view_only_inlines(self, has_change_permission):
|
||||||
|
"""User with add permission to a section but view-only for inlines."""
|
||||||
|
self.viewuser.user_permissions.add(get_perm(Section, get_permission_codename('add', Section._meta)))
|
||||||
|
self.client.force_login(self.viewuser)
|
||||||
|
# Valid POST creates a new section.
|
||||||
|
data = {
|
||||||
|
'name': 'New obj',
|
||||||
|
'article_set-TOTAL_FORMS': 0,
|
||||||
|
'article_set-INITIAL_FORMS': 0,
|
||||||
|
}
|
||||||
|
response = self.client.post(reverse('admin:admin_views_section_add'), data)
|
||||||
|
self.assertRedirects(response, reverse('admin:index'))
|
||||||
|
self.assertEqual(Section.objects.latest('id').name, data['name'])
|
||||||
|
# InlineModelAdmin.has_change_permission()'s obj argument is always
|
||||||
|
# None during object add.
|
||||||
|
self.assertEqual([obj for (request, obj), _ in has_change_permission.call_args_list], [None, None])
|
||||||
|
|
||||||
def test_change_view(self):
|
def test_change_view(self):
|
||||||
"""Change view should restrict access and allow users to edit items."""
|
"""Change view should restrict access and allow users to edit items."""
|
||||||
change_dict = {'title': 'Ikke fordømt',
|
change_dict = {'title': 'Ikke fordømt',
|
||||||
|
|
Loading…
Reference in New Issue