Skip to content

Instantly share code, notes, and snippets.

@allanlei
Created January 10, 2013 07:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save allanlei/4500296 to your computer and use it in GitHub Desktop.
Save allanlei/4500296 to your computer and use it in GitHub Desktop.
Subclass of mongoengine's GenericEmbeddedDocumentField. Allows GenericEmbeddedDocumentField to read a custom field instead of _cls to construct the EmbeddedDocument.
from mongoengine.fields import GenericEmbeddedDocumentField as MDBGenericEmbeddedDocumentField
class GenericEmbeddedDocumentField(MDBGenericEmbeddedDocumentField):
def __init__(self, *args, **kwargs):
self.cls_field = kwargs.pop('cls_field', '_cls')
super(GenericEmbeddedDocumentField, self).__init__(*args, **kwargs)
def to_python(self, value):
cls = None
if isinstance(self.cls_field, (str, unicode)):
cls = value[self.cls_field]
elif hasattr(self.cls_field, '__call__'):
cls = self.cls_field(value)
if cls is not None and isinstance(value, dict):
value.update({
'_cls': cls,
})
return super(GenericEmbeddedDocumentField, self).to_python(value)
def to_mongo(self, document):
if document is None:
return None
data = document.to_mongo()
# if not '_cls' in data:
# data['_cls'] = document._class_name
return data
from fields import GenericEmbeddedDocumentField
PAYMENT_MAPPING = {
'credit card': 'CreditCardPayment',
'cheque': 'ChequePayment',
}
class Payment(db.EmbeddedDocument):
price = db.IntField()
currency = db.StringField()
payment_type = db.StringField(choices=['credit card', 'cheque'])
meta = {
'allow_inheritance': False,
'abstract': True,
}
class CreditCardPayment(Payment):
meta = {
'allow_inheritance': False,
}
class ChequePayment(Payment):
meta = {
'allow_inheritance': False,
}
class MyModel(db.Document):
payment = GenericEmbeddedDocumentField(choices=[CreditCardPayment, ChequePayment], cls_field=lambda value: PAYMENT_MAPPING[value['payment_type']])
@brendo10x
Copy link

Excellent tutorial!! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment