Skip to content

Commit 7d2f3d9

Browse files
committed
Issue #16: Possibility to mark filed as required.
1 parent 9ed9d74 commit 7d2f3d9

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

domain_models/fields.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class Field(property):
1111
"""Base field."""
1212

13-
def __init__(self, default=None):
13+
def __init__(self, default=None, required=False):
1414
"""Initializer."""
1515
super(Field, self).__init__(self.get_value, self.set_value)
1616
self.name = None
@@ -19,6 +19,7 @@ def __init__(self, default=None):
1919
self.model_cls = None
2020

2121
self.default = default
22+
self.required = required
2223

2324
def bind_name(self, name):
2425
"""Bind field to its name in model class."""
@@ -40,8 +41,12 @@ def bind_model_cls(self, model_cls):
4041

4142
def init_model(self, model, value):
4243
"""Init model with field."""
43-
if not value:
44+
if value is None:
4445
value = self.default() if callable(self.default) else self.default
46+
47+
if value is None and self.required:
48+
raise AttributeError("This field is required.")
49+
4550
setattr(model, self.storage_name, value)
4651

4752
def get_value(self, model):
@@ -50,6 +55,9 @@ def get_value(self, model):
5055

5156
def set_value(self, model, value):
5257
"""Set field's value."""
58+
if value is None and self.required:
59+
raise AttributeError("This field is required.")
60+
5361
if value is not None:
5462
value = self._converter(value)
5563
setattr(model, self.storage_name, value)

tests/test_fields.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class ExampleModel(models.DomainModel):
2222
field = fields.Field()
2323
field_default = fields.Field(default=123)
2424
field_default_callable = fields.Field(default=time.time)
25+
field_required_default = fields.Field(default=123, required=True)
2526

2627
bool_field = fields.Bool()
2728

@@ -38,6 +39,11 @@ class ExampleModel(models.DomainModel):
3839
collection_field = fields.Collection(RelatedModel)
3940

4041

42+
class RequiredFieldModel(models.DomainModel):
43+
"""Example model for required fields."""
44+
field_required = fields.Field(required=True)
45+
46+
4147
class FieldTest(unittest.TestCase):
4248
"""Base field tests."""
4349

@@ -81,6 +87,37 @@ def test_field_default_callable(self):
8187
self.assertGreater(model2.field_default_callable,
8288
model1.field_default_callable)
8389

90+
def test_field_required(self):
91+
"""Test required field with default value."""
92+
model = ExampleModel()
93+
self.assertEquals(model.field_required_default, 123)
94+
95+
def test_field_required_set_valid(self):
96+
"""Test required field with valid value."""
97+
model = ExampleModel()
98+
model.field_required_default = False
99+
self.assertIs(model.field_required_default, False)
100+
101+
def test_field_required_set_invalid(self):
102+
"""Test required field with invalid value."""
103+
model = ExampleModel()
104+
with self.assertRaises(AttributeError):
105+
model.field_required_default = None
106+
107+
def test_field_required_init_valid_model(self):
108+
"""Test required field with valid value as model keyword."""
109+
model = RequiredFieldModel(field_required=False)
110+
self.assertIs(model.field_required, False)
111+
model.field_required = 123
112+
self.assertEqual(model.field_required, 123)
113+
114+
def test_field_required_init_invalid_model(self):
115+
"""Test required field with invalid value as model keyword."""
116+
with self.assertRaises(AttributeError):
117+
RequiredFieldModel()
118+
with self.assertRaises(AttributeError):
119+
RequiredFieldModel(field_required=None)
120+
84121

85122
class BoolTest(unittest.TestCase):
86123
"""Bool field tests."""

0 commit comments

Comments
 (0)