Skip to content

Commit adefed0

Browse files
authored
Merge pull request #97 from AccentDesign/tidy_streamfield
better streamfield init of registered fields
2 parents 046a49f + fadb66d commit adefed0

3 files changed

Lines changed: 95 additions & 4 deletions

File tree

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99

1010
install_requires = [
11-
'Django>=2,<2.1',
1211
'wagtail>=2,<2.2'
1312
]
1413

tests/fields/test_streamfield.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from django import forms
2+
from django.core.exceptions import ImproperlyConfigured
3+
4+
from wagtailstreamforms.streamfield import FormFieldsStreamField
5+
from wagtailstreamforms import fields
6+
7+
from ..test_case import AppTestCase
8+
9+
10+
class GoodField(fields.BaseField):
11+
field_class = forms.CharField
12+
13+
14+
class TestCorrectTypeRegistering(AppTestCase):
15+
16+
@classmethod
17+
def setUpClass(cls):
18+
fields.register('good', GoodField)
19+
20+
@classmethod
21+
def tearDownClass(cls):
22+
del fields._fields['good']
23+
24+
def test_child_blocks(self):
25+
field = FormFieldsStreamField([])
26+
self.assertIn('good', field.stream_block.child_blocks)
27+
28+
def test_dependencies(self):
29+
field = FormFieldsStreamField([])
30+
self.assertListEqual(
31+
[b.__class__ for b in field.stream_block.dependencies],
32+
[b.__class__ for b in field.stream_block.child_blocks.values()]
33+
)
34+
35+
36+
class BadField:
37+
field_class = forms.CharField
38+
39+
40+
class TestIncorrectTypeRegistering(AppTestCase):
41+
42+
@classmethod
43+
def setUpClass(cls):
44+
fields.register('bad', BadField)
45+
46+
@classmethod
47+
def tearDownClass(cls):
48+
del fields._fields['bad']
49+
50+
def test_is_invalid_class(self):
51+
expected_error = "'%s' must be a subclass of '%s'" % (BadField, fields.BaseField)
52+
53+
with self.assertRaises(ImproperlyConfigured) as e:
54+
FormFieldsStreamField([])
55+
56+
self.assertEqual(e.exception.args[0], expected_error)

wagtailstreamforms/streamfield.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,46 @@
1+
from django.core.exceptions import ImproperlyConfigured
2+
3+
from wagtail.core import blocks
14
from wagtail.core.fields import StreamField
5+
from wagtailstreamforms.fields import get_fields, BaseField
26

3-
from wagtailstreamforms.fields import get_fields
47

8+
class FormFieldStreamBlock(blocks.StreamBlock):
9+
""" Add all registered instances of BaseField's get_form_block method to the streamfield. """
510

6-
class FormFieldsStreamField(StreamField):
11+
def __init__(self, local_blocks=None, **kwargs):
12+
self._constructor_kwargs = kwargs
13+
14+
# Note, this is calling BaseStreamBlock's super __init__, not FormFieldStreamBlock's.
15+
# We don't want BaseStreamBlock.__init__() to run, because it tries to assign to self.child_blocks,
16+
# which we've overridden with a @property. But we DO want Block.__init__() to run.
17+
super(blocks.BaseStreamBlock, self).__init__()
18+
19+
self._child_blocks = self.base_blocks.copy()
20+
21+
for name, field_class in get_fields().items():
22+
23+
# ensure the field is a subclass of BaseField.
24+
if not issubclass(field_class, BaseField):
25+
raise ImproperlyConfigured("'%s' must be a subclass of '%s'" % (field_class, BaseField))
726

27+
# assign the block
28+
block = field_class().get_form_block()
29+
block.set_name(name)
30+
self._child_blocks[name] = block
31+
32+
self._dependencies = self._child_blocks.values()
33+
34+
@property
35+
def child_blocks(self):
36+
return self._child_blocks
37+
38+
@property
39+
def dependencies(self):
40+
return self._dependencies
41+
42+
43+
class FormFieldsStreamField(StreamField):
844
def __init__(self, block_types, **kwargs):
9-
block_types = [(key, item().get_form_block()) for key, item in get_fields().items()]
1045
super().__init__(block_types, **kwargs)
46+
self.stream_block = FormFieldStreamBlock(block_types, required=not self.blank)

0 commit comments

Comments
 (0)