Added connect(), document data now stored as Python
Added document length, contains, etc with tests
This commit is contained in:
parent
0bb0ec0114
commit
688fd5af66
@ -3,7 +3,38 @@ from document import *
|
||||
import fields
|
||||
from fields import *
|
||||
|
||||
__all__ = document.__all__ + fields.__all__
|
||||
from pymongo import Connection
|
||||
|
||||
__all__ = document.__all__ + fields.__all__ + ['connect']
|
||||
|
||||
__author__ = 'Harry Marr'
|
||||
__version__ = '0.1'
|
||||
|
||||
_connection_settings = {
|
||||
'host': 'localhost',
|
||||
'port': 27017,
|
||||
'pool_size': 1,
|
||||
}
|
||||
_connection = None
|
||||
_db = None
|
||||
|
||||
def _get_connection():
|
||||
if _connection is None:
|
||||
_connection = Connection(**_connection_settings)
|
||||
return _connection
|
||||
|
||||
def connect(db=None, username=None, password=None, **kwargs):
|
||||
"""Connect to the database specified by the 'db' argument. Connection
|
||||
settings may be provided here as well if the database is not running on
|
||||
the default port on localhost. If authentication is needed, provide
|
||||
username and password arguments as well.
|
||||
"""
|
||||
if db is None:
|
||||
raise TypeError('"db" argument must be provided to connect()')
|
||||
|
||||
_connection_settings.update(kwargs)
|
||||
connection = _get_connection()
|
||||
# Get DB from connection and auth if necessary
|
||||
_db = connection[db]
|
||||
if username is not None and password is not None:
|
||||
_db.authenticate(username, password)
|
||||
|
@ -24,12 +24,13 @@ class BaseField(object):
|
||||
|
||||
# Get value from document instance if available, if not use default
|
||||
value = instance._data.get(self.name)
|
||||
if value is not None:
|
||||
value = self._to_python(value)
|
||||
elif self.default is not None:
|
||||
if value is None:
|
||||
if self.default is not None:
|
||||
value = self.default
|
||||
if callable(value):
|
||||
value = value()
|
||||
else:
|
||||
raise AttributeError(self.name)
|
||||
return value
|
||||
|
||||
def __set__(self, instance, value):
|
||||
@ -40,7 +41,6 @@ class BaseField(object):
|
||||
try:
|
||||
value = self._to_python(value)
|
||||
self._validate(value)
|
||||
value = self._to_mongo(value)
|
||||
except ValueError:
|
||||
raise ValidationError('Invalid value for field of type "' +
|
||||
self.__class__.__name__ + '"')
|
||||
@ -61,7 +61,7 @@ class BaseField(object):
|
||||
def _validate(self, value):
|
||||
"""Perform validation on a value.
|
||||
"""
|
||||
return value
|
||||
pass
|
||||
|
||||
|
||||
class DocumentMetaclass(type):
|
||||
@ -143,7 +143,7 @@ class BaseDocument(object):
|
||||
if attr_value.required:
|
||||
raise ValidationError('Field "%s" is required' % self.name)
|
||||
# Use default value
|
||||
setattr(self, attr_name, getattr(self, attr_name))
|
||||
setattr(self, attr_name, getattr(self, attr_name, None))
|
||||
|
||||
def __iter__(self):
|
||||
# Use _data rather than _fields as iterator only looks at names so
|
||||
@ -166,6 +166,16 @@ class BaseDocument(object):
|
||||
raise KeyError(name)
|
||||
return setattr(self, name, value)
|
||||
|
||||
def __contains__(self, name):
|
||||
try:
|
||||
getattr(self, name)
|
||||
return True
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
def __len__(self):
|
||||
return len(self._data)
|
||||
|
||||
def _to_mongo(self):
|
||||
"""Return data dictionary ready for use with MongoDB.
|
||||
"""
|
||||
|
@ -61,6 +61,13 @@ class DocumentTest(unittest.TestCase):
|
||||
person['name'] = 'Another User'
|
||||
self.assertEquals(person['name'], 'Another User')
|
||||
|
||||
self.assertEquals(len(person), 2)
|
||||
|
||||
self.assertTrue('age' in person)
|
||||
person.age = None
|
||||
self.assertFalse('age' in person)
|
||||
self.assertFalse('nationality' in person)
|
||||
|
||||
def test_embedded_document(self):
|
||||
"""Ensure that embedded documents are set up correctly.
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user