Skip to content

Commit

Permalink
Issue 53 -- Separate DB-initated object field setting from user intiated
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff Jenkins committed Apr 7, 2011
1 parent 53cf3b7 commit b23f69b
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 20 deletions.
36 changes: 22 additions & 14 deletions examples/advanced_modeling.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
'''
This page is going to go through some more advanced modeling techniques
using forward and self-references
'''


from mongoalchemy.document import Document, DocumentField
from mongoalchemy.fields import *
from datetime import datetime

from pprint import pprint
class Event(Document):
name = StringField()
children = ListField(DocumentField('Event'), default=[])
start = DateTimeField()
children = ListField(DocumentField('Event'))
begin = DateTimeField()
end = DateTimeField()

def __init__(self, name, parent=None):
Document.__init__(self, name=name)
self.children = []
if parent != None:
parent.children.append(self)
def __enter__(self):
self.start = datetime.utcnow()
self.begin = datetime.utcnow()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = datetime.utcnow()

root = Event('request')
with Event('main_func', root) as br:
with Event('setup', br):
pass
with Event('handle', br):
pass
with Event('teardown', br):
with Event('request') as root:
with Event('main_func', root) as br:
with Event('setup', br):
pass
with Event('handle', br):
pass
with Event('teardown', br):
pass
with Event('cleanup', root):
pass
with Event('cleanup', root):
pass

print root.wrap()
pprint(root.wrap())
30 changes: 30 additions & 0 deletions examples/hash_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from mongoalchemy.document import Document, DocumentField
from mongoalchemy.fields import *
from datetime import datetime
from pprint import pprint

class HashField(StringField):
def set_value(self, instance, value, from_db=False):
if from_db:
super(HashField, self).set_value(instance, value)
else:
super(HashField, self).set_value(instance, str(hash(value)))

class User(Document):
password = HashField()

from mongoalchemy.session import Session
session = Session.connect('mongoalchemy-tutorial')
session.clear_collection(User)

user = User(password='pw')
print user.password
user.password = 'newpw'
print user.password

session.insert(user)

loaded_user = session.query(User).one()

print loaded_user.password
print loaded_user.password
6 changes: 3 additions & 3 deletions mongoalchemy/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class Document(object):
fields which couldn't be mapped can be retrieved (and edited) using
:func:`~Document.get_extra_fields` '''

def __init__(self, retrieved_fields=None, **kwargs):
def __init__(self, retrieved_fields=None, loading_from_db=False, **kwargs):
''' :param retrieved_fields: The names of the fields returned when loading \
a partial object. This argument should not be explicitly set \
by subclasses
Expand All @@ -141,7 +141,7 @@ def __init__(self, retrieved_fields=None, **kwargs):
continue

if name in kwargs:
setattr(self, name, kwargs[name])
getattr(cls, name).set_value(self, kwargs[name], from_db=loading_from_db)
continue

for k in kwargs:
Expand Down Expand Up @@ -315,7 +315,7 @@ def unwrap(cls, obj, fields=None):

if fields != None:
params['retrieved_fields'] = fields
obj = cls(**params)
obj = cls(loading_from_db=True, **params)
obj.__mark_clean()
return obj

Expand Down
9 changes: 6 additions & 3 deletions mongoalchemy/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,19 @@ def __get__(self, instance, owner):


def __set__(self, instance, value):
instance._field_values[self.name] = value
if self.on_update != 'ignore':
instance._dirty[self.name] = self.on_update
self.set_value(instance, value)

def __delete__(self, instance):
if self.name not in instance._field_values:
raise AttributeError(self.name)
del instance._field_values[self.name]
instance._dirty[self.name] = '$unset'

def set_value(self, instance, value, from_db=False):
instance._field_values[self.name] = value
if self.on_update != 'ignore':
instance._dirty[self.name] = self.on_update

def dirty_ops(self, instance):
op = instance._dirty.get(self.name)
if op == '$unset':
Expand Down

0 comments on commit b23f69b

Please sign in to comment.