Skip to content
Browse files

Adding default_f, allowing a function to be used to define a field's

default value.  default_empty has been converted to using this
  • Loading branch information...
1 parent 885c5ee commit 130470db99825861d1095a8dc103f273db33958e @jeffjenkins committed Feb 24, 2013
View
34 mongoalchemy/fields/base.py
@@ -136,8 +136,8 @@ class Field(object):
valid_modifiers = SCALAR_MODIFIERS
- def __init__(self, required=True, default=UNSET, db_field=None,
- allow_none=False, on_update='$set',
+ def __init__(self, required=True, default=UNSET, default_f=None,
+ db_field=None, allow_none=False, on_update='$set',
validator=None, unwrap_validator=None, wrap_validator=None,
_id=False, proxy=None, iproxy=None, ignore_missing=False):
'''
@@ -180,16 +180,28 @@ def __init__(self, required=True, default=UNSET, db_field=None,
self._allow_none = allow_none
self.required = required
- self.default = default
+ self._default = default
+ self._default_f = default_f
+ if self._default_f and self._default != UNSET:
+ raise InvalidConfigException('Only one of default and default_f '
+ 'is allowed')
+
if default is None:
self._allow_none = True
self._owner = None
if on_update not in self.valid_modifiers and on_update != 'ignore':
- raise InvalidConfigException('Unsupported update operation: %s' % on_update)
+ raise InvalidConfigException('Unsupported update operation: %s'
+ % on_update)
self.on_update = on_update
self._name = 'Unbound_%s' % self.__class__.__name__
+
+ @property
+ def default(self):
+ if self._default_f:
+ return self._default_f()
+ return self._default
def schema_json(self):
schema = dict(
@@ -203,10 +215,12 @@ def schema_json(self):
wrap_validator=self.wrap_validator is not None,
ignore_missing=self.ignore_missing,
)
- if self.default == UNSET:
+ if self._default == UNSET and self._default_f is None:
schema['default_unset'] = True
+ elif self._default_f:
+ schema['default_f'] = repr(self._default_f)
else:
- schema['default'] = self.wrap(self.default)
+ schema['default'] = self.wrap(self._default)
return schema
@@ -220,8 +234,12 @@ def __get__(self, instance, owner):
return instance._values[self._name].value
# if not, try the default
- if self.default is not UNSET:
- self.set_value(instance, self.default)
+ print self._default, self._default_f
+ if self._default_f:
+ self.set_value(instance, self._default_f())
+ return instance._values[self._name].value
+ elif self._default is not UNSET:
+ self.set_value(instance, self._default)
return instance._values[self._name].value
# If this value wasn't retrieved, raise a specific exception
View
17 mongoalchemy/fields/fields.py
@@ -402,19 +402,20 @@ class ObjectIdField(Field):
valid_modifiers = SCALAR_MODIFIERS
def __init__(self, session=None, auto=False, **kwargs):
+ if auto:
+ kwargs['default_f'] = lambda : ObjectId()
super(ObjectIdField, self).__init__(**kwargs)
- self.auto = auto
def schema_json(self):
super_schema = super(ObjectIdField, self).schema_json()
return dict(auth=self.auto, **super_schema)
- def set_default(self, value):
- self._default = value
- def get_default(self):
- if self.auto:
- self._default = ObjectId()
- return self._default
- default = property(get_default, set_default)
+ # def set_default(self, value):
+ # super(ObjectIdField, self).set_default(value)
+ # def get_default(self):
+ # if self.auto:
+ # self.set_default(ObjectId())
+ # return super(ObjectIdField, self).get_default()
+ # default = property(get_default, set_default)
def gen(self):
return ObjectId()
View
24 mongoalchemy/fields/mapping.py
@@ -34,18 +34,21 @@ class DictField(Field):
def __init__(self, value_type, default_empty=False, **kwargs):
''' :param value_type: the Field type to use for the values
'''
+ if default_empty:
+ kwargs['default_f'] = dict
super(DictField, self).__init__(**kwargs)
self.value_type = value_type
self.default_empty = default_empty
+
if not isinstance(value_type, Field):
raise BadFieldSpecification("DictField value type is not a field!")
- def set_default(self, value):
- self._default = value
- def get_default(self):
- if self.default_empty:
- return {}
- return self._default
- default = property(get_default, set_default)
+ # def set_default(self, value):
+ # return super(DictField, self).set_default(value)
+ # def get_default(self):
+ # if self.default_empty:
+ # return {}
+ # return super(DictField, self).get_default()
+ # default = property(get_default, set_default)
def schema_json(self):
super_schema = super(DictField, self).schema_json()
return dict(value_type=self.value_type.schema_json(),
@@ -126,8 +129,11 @@ def __init__(self, key_type, value_type, default_empty=False, **kwargs):
''' :param key_type: the Field type to use for the keys
:param value_type: the Field type to use for the values
'''
- super(KVField, self).__init__(value_type, default_empty=default_empty, **kwargs)
-
+ if default_empty:
+ kwargs['default_f'] = dict
+ super(KVField, self).__init__(value_type, **kwargs)
+ self.default_empty = default_empty
+
if not isinstance(key_type, Field):
raise BadFieldSpecification("KVField key type is not a field!")
# This is covered by DictField
View
40 mongoalchemy/fields/sequence.py
@@ -153,14 +153,16 @@ def __init__(self, item_type, **kwargs):
:param max_capacity: maximum number of items contained in values
:param default_empty: the default is an empty sequence.
'''
+ if kwargs.get('default_empty'):
+ kwargs['default_f'] = list
super(ListField, self).__init__(item_type, **kwargs)
- def set_default(self, value):
- self._default = value
- def get_default(self):
- if self.default_empty:
- return []
- return self._default
- default = property(get_default, set_default)
+ # def set_default(self, value):
+ # return super(ListField, self).set_default(value)
+ # def get_default(self):
+ # if self.default_empty:
+ # return []
+ # return super(ListField, self).get_default()
+ # default = property(get_default, set_default)
def rel(self, ignore_missing=False):
from mongoalchemy.fields import RefBase
@@ -193,13 +195,23 @@ class SetField(SequenceField):
''' Field representing a python set.
.. seealso:: :class:`SequenceField`'''
- def set_default(self, value):
- self._default = value
- def get_default(self):
- if self.default_empty:
- return set()
- return self._default
- default = property(get_default, set_default)
+ def __init__(self, item_type, **kwargs):
+ ''' :param item_type: :class:`Field` instance used for validation and (un)wrapping
+ :param min_capacity: minimum number of items contained in values
+ :param max_capacity: maximum number of items contained in values
+ :param default_empty: the default is an empty sequence.
+ '''
+ if kwargs.get('default_empty'):
+ kwargs['default_f'] = set
+ super(SetField, self).__init__(item_type, **kwargs)
+
+ # def set_default(self, value):
+ # return super(SetField, self).set_default(value)
+ # def get_default(self):
+ # if self.default_empty:
+ # return set()
+ # return super(SetField, self).get_default()
+ # default = property(get_default, set_default)
def rel(self, ignore_missing=False):
return ListProxy(self, ignore_missing=ignore_missing)
View
5 test/test_fields.py
@@ -42,6 +42,10 @@ def test_id_attr():
assert IntField(_id=True).is_id == True
@raises(InvalidConfigException)
+def test_double_default():
+ IntField(default=1, default_f=lambda: 1)
+
+@raises(InvalidConfigException)
def test_bad_id_attr():
IntField(db_field='foo', _id=True)
@@ -212,6 +216,7 @@ def test_object_id_auto():
from mongoalchemy.document import Document
class A(Document):
idf = ObjectIdField(auto=True, required=False)
+ print A().idf
assert 'idf' in A().wrap()
#ObjectID Field
View
2 test/test_schema_tools.py
@@ -18,6 +18,7 @@ class SchemaTestDoc(BaseDoc):
enum = EnumField(AnythingField(), "a")
anyf = AnythingField()
default_field = IntField(default=2)
+ defaultf_field = IntField(default_f=lambda : 3)
modified = ModifiedField()
dict_field = DictField(AnythingField())
list_field = ListField(AnythingField())
@@ -66,6 +67,7 @@ def test_schema():
# assert False,
contains(fields['default_field'], {'default' : 2})
+ 'function' in fields['defaultf_field'].get('default_f', '')
# Computed Field
mod = fields['modified']

0 comments on commit 130470d

Please sign in to comment.
Something went wrong with that request. Please try again.