Skip to content

Commit dc6fc0e

Browse files
authored
Make admin views respect apps__*__include (iommirocks#695)
1 parent ed81e89 commit dc6fc0e

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed

iommi/admin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ class Meta:
151151

152152
@read_config
153153
@with_defaults(
154+
include=lambda admin, **_: (
155+
admin.app_name is None
156+
or admin.apps.get(admin.app_name+'_'+admin.model_name, Namespace(include=False)).include is True
157+
),
154158
apps__auth_user__include=True,
155159
parts__edit_auth_user__fields__password__write_to_instance=lambda instance, value, **_: instance.set_password(value),
156160
parts__edit_auth_user__fields__password__read_from_instance=lambda **_: '',

iommi/admin__tests.py

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def test_bulk_edit_for_non_unique(settings):
3737
request = staff_req('get')
3838
result = (
3939
Admin.list(
40+
apps__tests_adminunique__include=True,
4041
parts__list_tests_adminunique__columns__foo__bulk__include=True,
4142
)
4243
.refine_with_params(
@@ -48,22 +49,25 @@ def test_bulk_edit_for_non_unique(settings):
4849

4950
assert [x._name for x in values(result.parts.list_tests_adminunique.columns) if x.bulk.include] == ['foo']
5051

52+
class FooAdmin(Admin):
53+
class Meta:
54+
apps__tests_foo__include = True
5155

5256
@pytest.mark.django_db
5357
@mock.patch('iommi.admin.messages')
5458
def test_create(mock_messages, settings):
5559
settings.ROOT_URLCONF = __name__
5660

5761
request = staff_req('get')
58-
c = Admin.create().refine_with_params(app_name='tests', model_name='foo')
62+
c = FooAdmin.create().refine_with_params(app_name='tests', model_name='foo')
5963
p = c.bind(request=request)
6064
assert list(p.parts.create_tests_foo.fields.keys()) == ['foo']
6165

6266
assert Foo.objects.count() == 0
6367

6468
# Check access control for not logged in
6569
request = req('post', foo=7, **{'-submit': ''})
66-
view = Admin.create().as_view()
70+
view = FooAdmin.create().as_view()
6771
assert isinstance(view(request, app_name='tests', model_name='foo'), HttpResponseRedirect)
6872
assert Foo.objects.count() == 0
6973

@@ -74,7 +78,7 @@ def test_create(mock_messages, settings):
7478

7579
# Now for real
7680
request = staff_req('post', foo=7, **{'-submit': ''})
77-
c = Admin.create().refine_with_params(app_name='tests', model_name='foo')
81+
c = FooAdmin.create().refine_with_params(app_name='tests', model_name='foo')
7882
p = c.bind(request=request)
7983
assert p.parts.create_tests_foo.is_valid()
8084
p.render_to_response()
@@ -95,7 +99,7 @@ def test_edit(mock_messages, settings):
9599
assert Foo.objects.count() == 0
96100
f = Foo.objects.create(foo=7)
97101

98-
c = Admin.edit().refine_with_params(app_name='tests', model_name='foo', pk=f.pk)
102+
c = FooAdmin.edit().refine_with_params(app_name='tests', model_name='foo', pk=f.pk)
99103
request = staff_req('post', foo=11, **{'-submit': ''})
100104
p = c.bind(request=request)
101105
assert p.parts.edit_tests_foo.is_valid()
@@ -114,7 +118,7 @@ def test_delete(mock_messages, settings):
114118
assert Foo.objects.count() == 0
115119
f = Foo.objects.create(foo=7)
116120

117-
c = Admin.delete().refine_with_params(app_name='tests', model_name='foo', pk=f.pk)
121+
c = FooAdmin.delete().refine_with_params(app_name='tests', model_name='foo', pk=f.pk)
118122
request = staff_req('post', **{'-submit': ''})
119123
p = c.bind(request=request)
120124
assert p.parts.delete_tests_foo.is_valid(), p.parts.delete_tests_foo.get_errors()
@@ -131,10 +135,10 @@ def test_delete(mock_messages, settings):
131135
@pytest.mark.parametrize(
132136
'admin, kwargs',
133137
[
134-
(Admin.all_models(), dict()),
135-
(Admin.list(), dict(app_name='tests', model_name='foo')),
136-
(Admin.edit(), dict(app_name='tests', model_name='foo', pk=0)),
137-
(Admin.delete(), dict(app_name='tests', model_name='foo', pk=0)),
138+
(FooAdmin.all_models(), dict()),
139+
(FooAdmin.list(), dict(app_name='tests', model_name='foo')),
140+
(FooAdmin.edit(), dict(app_name='tests', model_name='foo', pk=0)),
141+
(FooAdmin.delete(), dict(app_name='tests', model_name='foo', pk=0)),
138142
],
139143
)
140144
def test_redirect_to_login(settings, is_authenticated, admin, kwargs):
@@ -174,6 +178,38 @@ def test_404_for_non_staff(settings, admin, kwargs):
174178
view(request=request, **kwargs)
175179

176180

181+
@pytest.mark.django_db
182+
@pytest.mark.parametrize(
183+
'success, admin, kwargs',
184+
[
185+
(False, Admin.list(), dict(app_name='tests', model_name='foo')),
186+
(False, Admin.edit(), dict(app_name='tests', model_name='foo', pk=0)),
187+
(False, Admin.delete(), dict(app_name='tests', model_name='foo', pk=0)),
188+
(False, Admin.list(apps__tests_foo__include=False), dict(app_name='tests', model_name='foo')),
189+
(False, Admin.edit(apps__tests_foo__include=False), dict(app_name='tests', model_name='foo', pk=0)),
190+
(False, Admin.delete(apps__tests_foo__include=False), dict(app_name='tests', model_name='foo', pk=0)),
191+
(True, Admin.list(apps__tests_foo__include=True), dict(app_name='tests', model_name='foo')),
192+
(True, Admin.edit(apps__tests_foo__include=True), dict(app_name='tests', model_name='foo', pk=0)),
193+
(True, Admin.delete(apps__tests_foo__include=True), dict(app_name='tests', model_name='foo', pk=0)),
194+
],
195+
)
196+
def test_404_for_non_include(settings, success, admin, kwargs):
197+
settings.ROOT_URLCONF = __name__
198+
if 'pk' in kwargs:
199+
Foo.objects.create(pk=kwargs['pk'], foo=1)
200+
view = admin.as_view()
201+
request = user_req('get')
202+
request.user = Struct(is_staff=True, is_authenticated=True, is_superuser=True)
203+
204+
if success:
205+
result = view(request=request, **kwargs)
206+
assert result.status_code == 200
207+
else:
208+
with pytest.raises(Http404):
209+
view(request=request, **kwargs)
210+
211+
212+
177213
def test_messages():
178214
request = req('get')
179215
message = 'test message'
@@ -270,7 +306,7 @@ def test_no_config():
270306
@mock.patch('iommi.admin.messages')
271307
def test_create_non_int_pk(mock_messages, settings):
272308
request = staff_req('post', id=str(uuid4()), foo='banana', **{'-submit': ''})
273-
c = Admin.create().refine_with_params(app_name='tests', model_name='uuidpkmodel')
309+
c = FooAdmin.create(apps__tests_uuidpkmodel__include=True).refine_with_params(app_name='tests', model_name='uuidpkmodel')
274310
p = c.bind(request=request)
275311
assert p.parts.create_tests_uuidpkmodel.is_valid()
276312
p.render_to_response()
@@ -290,7 +326,7 @@ def test_edit_non_int_pk(mock_messages, settings):
290326
settings.ROOT_URLCONF = __name__
291327
f = UuidPKModel.objects.create(id=str(uuid4()), foo='banana')
292328

293-
c = Admin.edit().refine_with_params(app_name='tests', model_name='uuidpkmodel', pk=f.pk)
329+
c = Admin.edit(apps__tests_uuidpkmodel__include=True).refine_with_params(app_name='tests', model_name='uuidpkmodel', pk=f.pk)
294330
request = staff_req('post', id=f.pk, foo='orange', **{'-submit': ''})
295331
p = c.bind(request=request)
296332
assert p.parts.edit_tests_uuidpkmodel.is_valid(), p.parts.edit_tests_uuidpkmodel.get_errors()

iommi/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ def view_wrapper(request, **view_params):
4747
view_wrapper.__iommi_target__ = view_wrapper.__iommi_target__.refine_done()
4848

4949
decode_path_components(request, **view_params)
50-
return view_wrapper.__iommi_target__.bind(request=request).render_to_response()
50+
part = view_wrapper.__iommi_target__.bind(request=request)
51+
if part is None:
52+
from django.http import Http404
53+
raise Http404()
54+
return part.render_to_response()
5155

5256
view_wrapper.__name__ = f'{target.__class__.__name__}.as_view'
5357
view_wrapper.__doc__ = target.__class__.__doc__

0 commit comments

Comments
 (0)