mirror of
https://github.com/jazzband/django-admin2.git
synced 2026-04-30 11:34:48 +00:00
New immutable object type that is properly frozen. Part of #155
This commit is contained in:
parent
b2fb02b976
commit
096267c674
2 changed files with 50 additions and 0 deletions
36
djadmin2/tests/test_types.py
Normal file
36
djadmin2/tests/test_types.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from django.test import TestCase
|
||||
|
||||
from ..types import immutable_admin_factory
|
||||
|
||||
|
||||
class ModelAdmin(object):
|
||||
model_admin_attributes = ['a', 'b', 'c']
|
||||
a = 1 # covered
|
||||
b = 2 # covered
|
||||
c = 3 # covered
|
||||
d = 4 # not covered
|
||||
|
||||
|
||||
class ImmutableAdminFactoryTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.immutable_admin = immutable_admin_factory(ModelAdmin)
|
||||
|
||||
def test_immutability(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
# can't set attribute
|
||||
self.immutable_admin.a = 10
|
||||
with self.assertRaises(AttributeError):
|
||||
# 'ImmutableAdmin' object has no attribute 'e'
|
||||
self.immutable_admin.e = 5
|
||||
with self.assertRaises(AttributeError):
|
||||
# can't delete attribute
|
||||
del self.immutable_admin.a
|
||||
|
||||
def test_attributes(self):
|
||||
self.assertEquals(self.immutable_admin.a, 1)
|
||||
self.assertEquals(self.immutable_admin.b, 2)
|
||||
self.assertEquals(self.immutable_admin.c, 3)
|
||||
with self.assertRaises(AttributeError):
|
||||
# 'ImmutableAdmin' object has no attribute 'd'
|
||||
self.immutable_admin.d
|
||||
14
djadmin2/types.py
Normal file
14
djadmin2/types.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from collections import namedtuple
|
||||
|
||||
|
||||
def immutable_admin_factory(model_admin):
|
||||
""" Provide an ImmutableAdmin to make it harder for developers to dig themselves into holes.
|
||||
See https://github.com/twoscoops/django-admin2/issues/99
|
||||
Frozen class implementation as namedtuple suggested by Audrey Roy
|
||||
|
||||
Note: This won't stop developers from saving mutable objects to the result, but hopefully
|
||||
developers attempting that 'workaround/hack' will read our documentation.
|
||||
"""
|
||||
ImmutableAdmin = namedtuple("ImmutableAdmin", model_admin.model_admin_attributes, verbose=False)
|
||||
return ImmutableAdmin(*[getattr(model_admin, x) for x in model_admin.model_admin_attributes])
|
||||
|
||||
Loading…
Reference in a new issue