merged hmarr's updates

This commit is contained in:
blackbrrr
2009-12-19 14:31:17 -06:00
15 changed files with 277 additions and 68 deletions

View File

@@ -136,20 +136,36 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
if attrs.get('__metaclass__') == TopLevelDocumentMetaclass:
return super_new(cls, name, bases, attrs)
collection = attrs.get('__collection__', name.lower())
collection = name.lower()
simple_class = True
# Subclassed documents inherit collection from superclass
for base in bases:
if hasattr(base, '_meta') and 'collection' in base._meta:
# Ensure that the Document class may be subclassed -
# inheritance may be disabled to remove dependency on
# additional fields _cls and _types
if base._meta.get('allow_inheritance', True) == False:
raise ValueError('Document %s may not be subclassed' %
base.__name__)
else:
simple_class = False
collection = base._meta['collection']
meta = {
'collection': collection,
'allow_inheritance': True,
}
meta.update(attrs.get('meta', {}))
# Only simple classes - direct subclasses of Document - may set
# allow_inheritance to False
if not simple_class and not meta['allow_inheritance']:
raise ValueError('Only direct subclasses of Document may set '
'"allow_inheritance" to False')
attrs['_meta'] = meta
attrs['_id'] = ObjectIdField()
attrs['id'] = ObjectIdField(name='_id')
# Set up collection manager, needs the class to have fields so use
# DocumentMetaclass before instantiating CollectionManager object
@@ -168,10 +184,11 @@ class BaseDocument(object):
if attr_name in values:
setattr(self, attr_name, values.pop(attr_name))
else:
if attr_value.required:
# Use default value if present
value = getattr(self, attr_name, None)
if value is None and attr_value.required:
raise ValidationError('Field "%s" is required' % attr_name)
# Use default value
setattr(self, attr_name, getattr(self, attr_name, None))
setattr(self, attr_name, value)
@classmethod
def _get_subclasses(cls):
@@ -226,9 +243,12 @@ class BaseDocument(object):
for field_name, field in self._fields.items():
value = getattr(self, field_name, None)
if value is not None:
data[field_name] = field.to_mongo(value)
data['_cls'] = self._class_name
data['_types'] = self._superclasses.keys() + [self._class_name]
data[field.name] = field.to_mongo(value)
# Only add _cls and _types if allow_inheritance is not False
if not (hasattr(self, '_meta') and
self._meta.get('allow_inheritance', True) == False):
data['_cls'] = self._class_name
data['_types'] = self._superclasses.keys() + [self._class_name]
return data
@classmethod
@@ -241,6 +261,9 @@ class BaseDocument(object):
data = dict((str(key), value) for key, value in son.items())
if '_types' in data:
del data['_types']
if '_cls' in data:
del data['_cls']
@@ -254,7 +277,7 @@ class BaseDocument(object):
cls = subclasses[class_name]
for field_name, field in cls._fields.items():
if field_name in data:
data[field_name] = field.to_python(data[field_name])
if field.name in data:
data[field_name] = field.to_python(data[field.name])
return cls(**data)