Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding first sample implementation of fieldsets and fieldset objects #449

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions djadmin2/fieldsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
'''
Fieldset shall provide a interface that behaves like::

.. code-block:: python

fieldsets = Fieldsets(
Fieldset(
'information',
_('Information'),
fields=(
'title',
'description',
'links',
),
classes=('wide',)),
Fieldset(
'images',
'video',
'attribution',
id='media',
name=_('Media'),
classes=('wide',)),
)

fieldsets = fieldsets.move_fieldset('information', after='media')
fieldsets = fieldsets.move_field('images', after='video')
fieldsets = fieldsets.move_field('links', after='attribution')
fieldsets = fieldsets.add_field('a_field_that_was_not_yet_listed_in_the_fieldset', before='attribution')
fieldsets = fieldsets.remove_fieldset('media')
'''


class Fieldsets(object):
def __init__(self, *fieldsets):
self._fieldsets = []
for fieldset in fieldsets:
self.append(fieldset)

def __eq__(self, other):
return self._fieldsets == other._fieldsets

def __nonzero__(self):
return bool(self._fieldsets)

def __contains__(self, field):
'''
Checks if the given field is contained in one of the fieldsets.
'''
for fieldset in self._fieldsets:
if field in fieldset:
return True
return False

def __len__(self):
return len(self._fieldsets)

def __getitem__(self, key):
return self._fieldsets[key]

def copy(self):
return Fieldsets(*self._fieldsets)

@property
def fields(self):
fields = []
for fieldset in self._fieldsets:
fields.extend(fieldset.fields)
return fields

def append(self, fieldset):
self._fieldsets.append(fieldset)

def remove_fieldset(self, id):
if type(id) is int:
new = self.copy()
del new._fieldsets[id]
return new
else:
for i, fieldset in enumerate(self._fieldsets):
if fieldset.id == id:
new = self.copy()
del new._fieldsets[i]
return new
raise ValueError('Fieldset with id "{}" does not exist.'.format(id))

class Fieldset(object):
def __init__(self, *fields, **kwargs):
self._fields = list(fields)
self.id = kwargs.pop('id', None)
self.name = kwargs.pop('name', None)

def __eq__(self, other):
return self._fields == other._fields

def __nonzero__(self):
return bool(self._fields)

def __contains__(self, field):
return field in self._fields

def index(self, field):
return self._fields.index(field)

def copy(self):
return Fieldset(*self._fields)

@property
def fields(self):
return self._fields[:]

def _determine_new_index(self, after=None, before=None):
if before is None and after is None:
raise ValueError(
'Specify either `before` or `after` as argument.')
if before is not None and after is not None:
raise ValueError(
'You cannot specify `before` and `after` arguments at the '
'same time.')

# determine new index
if after is not None:
new_index = self._fields.index(after) + 1
elif before is not None:
new_index = self._fields.index(before)

return new_index

def add_field(self, field, after=None, before=None):
new_index = self._determine_new_index(after=after, before=before)
new = self.copy()
new._fields.insert(new_index, field)
return new

def move_field(self, field, after=None, before=None):
current_index = self._fields.index(field)
new_index = self._determine_new_index(after=after, before=before)
new = self.copy()
# insert into new place
new._fields.insert(new_index, field)
# remove current field
if new_index < current_index:
current_index += 1
del new._fields[current_index]
return new

def remove_field(self, field):
current_index = self._fields.index(field)
new = self.copy()
del new._fields[current_index]
return new
1 change: 1 addition & 0 deletions djadmin2/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from test_actions import *
from test_auth_admin import *
from test_renderers import *
from test_fieldsets import *
173 changes: 173 additions & 0 deletions djadmin2/tests/test_fieldsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
from django.test import TestCase
from ..fieldsets import Fieldsets, Fieldset


class FieldsetsTest(TestCase):
def test_contains(self):
fieldsets = Fieldsets()
self.assertFalse('name' in fieldsets)

fieldsets = Fieldsets(Fieldset())
self.assertFalse('name' in fieldsets)

fieldsets = Fieldsets(Fieldset('not_name'))
self.assertFalse('name' in fieldsets)

fieldsets = Fieldsets(Fieldset('name'))
self.assertTrue('name' in fieldsets)

fieldsets = Fieldsets(Fieldset('not_name', 'name'))
self.assertTrue('name' in fieldsets)

def test_empty(self):
fieldsets = Fieldsets()
self.assertFalse(fieldsets)

fieldsets = Fieldsets(Fieldset())
self.assertTrue(fieldsets)

def test_indexing(self):
fs = Fieldsets()
self.assertEqual(len(fs), 0)

foo = Fieldset('foo')
bar = Fieldset('bar')
spam = Fieldset('spam')
eggs = Fieldset('eggs')
fs = Fieldsets(foo, bar, spam, eggs)
self.assertEqual(len(fs), 4)
self.assertEqual(fs[0], foo)
self.assertEqual(fs[1], bar)
self.assertEqual(fs[2], spam)
self.assertEqual(fs[3], eggs)
self.assertEqual(fs[-1], eggs)

def test_slicing(self):
foo = Fieldset('foo')
bar = Fieldset('bar')
spam = Fieldset('spam')
eggs = Fieldset('eggs')
fs = Fieldsets(foo, bar, spam, eggs)

self.assertEqual(fs[0:2], [foo, bar])
self.assertEqual(fs[::-2], [eggs, bar])

def test_append(self):
fs = Fieldsets()
foo = Fieldset('foo')
bar = Fieldset('bar')
fs.append(foo)
fs.append(bar)
self.assertEqual(fs.fields, ['foo', 'bar'])

def test_copy(self):
foo = Fieldset('foo')
bar = Fieldset('bar')
f1 = Fieldsets(foo, bar)
f2 = f1.copy()
self.assertEqual(f1, f2)
self.assertFalse(f1 is f2)

f2 = f2.remove_fieldset(0)
self.assertNotEqual(f1, f2)
self.assertFalse(f1 is f2)

def test_remove_fieldset(self):
foo = Fieldset('foo', id='foo1')
bar = Fieldset('bar', id='foo2')
fs = Fieldsets(foo, bar)
fs.remove_fieldset('foo1')
self.assertEqual(fs.fields, ['foo', 'bar'])

fs = fs.remove_fieldset('foo1')
self.assertEqual(fs.fields, ['bar'])

self.assertRaises(ValueError, fs.remove_fieldset, 'foo1')


class FieldsetTest(TestCase):
def test_id(self):
f = Fieldset(id='my_id')
self.assertEqual(f.id, 'my_id')

def test_name(self):
f = Fieldset(name='A beautiful, descriptive name')
self.assertEqual(f.name, 'A beautiful, descriptive name')

def test_contains(self):
fieldset = Fieldset()
self.assertFalse('name' in fieldset)

fieldset = Fieldset('not_name')
self.assertFalse('name' in fieldset)

fieldset = Fieldset('name')
self.assertTrue('name' in fieldset)

fieldset = Fieldset('not_name', 'name')
self.assertTrue('name' in fieldset)

def test_empty(self):
fieldset = Fieldset()
self.assertFalse(fieldset)

fieldset = Fieldset('field_one')
self.assertTrue(fieldset)

def test_index(self):
f = Fieldset('foo', 'bar')
self.assertEqual(f.index('foo'), 0)
self.assertEqual(f.index('bar'), 1)
self.assertRaises(ValueError, f.index, None)
self.assertRaises(ValueError, f.index, 'non_existent')

def test_copy(self):
f1 = Fieldset('foo', 'bar')
f2 = f1.copy()
self.assertEqual(f1, f2)
self.assertFalse(f1 is f2)

f1.move_field('bar', after='foo')
self.assertNotEqual(f1, f2)

def test_add_field_before(self):
f1 = Fieldset('foo', 'bar')
f1 = f1.add_field('spam', before='bar')
self.assertEqual(f1.fields, ['foo', 'spam', 'bar'])
f1 = f1.add_field('eggs', before='foo')
self.assertEqual(f1.fields, ['eggs', 'foo', 'spam', 'bar'])

def test_add_field_after(self):
f1 = Fieldset('foo', 'bar')
f1 = f1.add_field('spam', after='foo')
self.assertEqual(f1.fields, ['foo', 'spam', 'bar'])
f1 = f1.add_field('eggs', after='bar')
self.assertEqual(f1.fields, ['foo', 'spam', 'bar', 'eggs'])

def test_move_field_errors(self):
f1 = Fieldset('foo', 'bar')

self.assertRaises(ValueError, f1.move_field, 'foo', after='bar', before='bar')
self.assertRaises(ValueError, f1.move_field, 'foo', 'bar', 'bar')

def test_move_field_before(self):
f1 = Fieldset('foo', 'bar', 'spam', 'eggs')
f1 = f1.move_field('foo', before='eggs')
self.assertEqual(f1.fields, ['bar', 'spam', 'foo', 'eggs'])

f1 = f1.move_field('spam', before='bar')
self.assertEqual(f1.fields, ['spam', 'bar', 'foo', 'eggs'])

def test_move_field_after(self):
f1 = Fieldset('foo', 'bar', 'spam', 'eggs')
f1 = f1.move_field('foo', after='bar')
self.assertEqual(f1.fields, ['bar', 'foo', 'spam', 'eggs'])

f1 = f1.move_field('foo', after='eggs')
self.assertEqual(f1.fields, ['bar', 'spam', 'eggs', 'foo'])

def test_remove_field(self):
f1 = Fieldset('foo', 'bar', 'spam', 'eggs')
f1 = f1.remove_field('foo')
self.assertEqual(f1.fields, ['bar', 'spam', 'eggs'])
self.assertRaises(ValueError, f1.remove_field, 'foo')