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
|
import fields
|
||||||
from fields import *
|
from fields import *
|
||||||
|
|
||||||
__all__ = document.__all__ + fields.__all__
|
from pymongo import Connection
|
||||||
|
|
||||||
|
__all__ = document.__all__ + fields.__all__ + ['connect']
|
||||||
|
|
||||||
__author__ = 'Harry Marr'
|
__author__ = 'Harry Marr'
|
||||||
__version__ = '0.1'
|
__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
|
# Get value from document instance if available, if not use default
|
||||||
value = instance._data.get(self.name)
|
value = instance._data.get(self.name)
|
||||||
if value is not None:
|
if value is None:
|
||||||
value = self._to_python(value)
|
if self.default is not None:
|
||||||
elif self.default is not None:
|
value = self.default
|
||||||
value = self.default
|
if callable(value):
|
||||||
if callable(value):
|
value = value()
|
||||||
value = value()
|
else:
|
||||||
|
raise AttributeError(self.name)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __set__(self, instance, value):
|
def __set__(self, instance, value):
|
||||||
@ -40,7 +41,6 @@ class BaseField(object):
|
|||||||
try:
|
try:
|
||||||
value = self._to_python(value)
|
value = self._to_python(value)
|
||||||
self._validate(value)
|
self._validate(value)
|
||||||
value = self._to_mongo(value)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError('Invalid value for field of type "' +
|
raise ValidationError('Invalid value for field of type "' +
|
||||||
self.__class__.__name__ + '"')
|
self.__class__.__name__ + '"')
|
||||||
@ -61,7 +61,7 @@ class BaseField(object):
|
|||||||
def _validate(self, value):
|
def _validate(self, value):
|
||||||
"""Perform validation on a value.
|
"""Perform validation on a value.
|
||||||
"""
|
"""
|
||||||
return value
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DocumentMetaclass(type):
|
class DocumentMetaclass(type):
|
||||||
@ -143,7 +143,7 @@ class BaseDocument(object):
|
|||||||
if attr_value.required:
|
if attr_value.required:
|
||||||
raise ValidationError('Field "%s" is required' % self.name)
|
raise ValidationError('Field "%s" is required' % self.name)
|
||||||
# Use default value
|
# Use default value
|
||||||
setattr(self, attr_name, getattr(self, attr_name))
|
setattr(self, attr_name, getattr(self, attr_name, None))
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
# Use _data rather than _fields as iterator only looks at names so
|
# Use _data rather than _fields as iterator only looks at names so
|
||||||
@ -161,11 +161,21 @@ class BaseDocument(object):
|
|||||||
def __setitem__(self, name, value):
|
def __setitem__(self, name, value):
|
||||||
"""Dictionary-style field access, set a field's value.
|
"""Dictionary-style field access, set a field's value.
|
||||||
"""
|
"""
|
||||||
# Ensure that the field exists before settings its value
|
# Ensure that the field exists before settings its value
|
||||||
if name not in self._fields:
|
if name not in self._fields:
|
||||||
raise KeyError(name)
|
raise KeyError(name)
|
||||||
return setattr(self, name, value)
|
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):
|
def _to_mongo(self):
|
||||||
"""Return data dictionary ready for use with MongoDB.
|
"""Return data dictionary ready for use with MongoDB.
|
||||||
"""
|
"""
|
||||||
|
@ -61,6 +61,13 @@ class DocumentTest(unittest.TestCase):
|
|||||||
person['name'] = 'Another User'
|
person['name'] = 'Another User'
|
||||||
self.assertEquals(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):
|
def test_embedded_document(self):
|
||||||
"""Ensure that embedded documents are set up correctly.
|
"""Ensure that embedded documents are set up correctly.
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user