def validate_fields(self): for name, field in self._fields.items(): value = self.get_field_value(name) if field.required and field.is_empty(value): raise InvalidDocumentError("Field '%s' is required." % name) if not field.validate(value): raise InvalidDocumentError("Field '%s' must be valid." % name) return True
def __new__(cls, name, bases, attrs): flattened_bases = cls._get_bases(bases) super_new = super(DocumentMetaClass, cls).__new__ doc_fields = {} for base in flattened_bases[::-1]: if hasattr(base, '_fields'): doc_fields.update(base._fields) # Discover any document fields field_names = {} for field_name, doc_field in doc_fields.items(): field_names[doc_field.db_field] = field_names.get( doc_field.db_field, 0) + 1 for attr_name, attr_value in attrs.items(): if not isinstance(attr_value, BaseField): continue attr_value.name = attr_name if not attr_value.db_field: attr_value.db_field = attr_name doc_fields[attr_name] = attr_value # Count names to ensure no db_field redefinitions field_names[attr_value.db_field] = field_names.get( attr_value.db_field, 0) + 1 # Ensure no duplicate db_fields duplicate_db_fields = [k for k, v in field_names.items() if v > 1] if duplicate_db_fields: msg = ("Multiple db_fields defined for: %s " % ", ".join(duplicate_db_fields)) raise InvalidDocumentError(msg) # Set _fields and db_field maps attrs['_fields'] = doc_fields attrs['_db_field_map'] = dict([(k, getattr(v, 'db_field', k)) for k, v in doc_fields.items()]) attrs['_fields_ordered'] = tuple(i[1] for i in sorted( (v.creation_counter, v.name) for v in doc_fields.values())) attrs['_reverse_db_field_map'] = dict( (v, k) for k, v in attrs['_db_field_map'].items()) new_class = super_new(cls, name, bases, attrs) if not '__collection__' in attrs: new_class.__collection__ = new_class.__name__ if not '__lazy__' in attrs: new_class.__lazy__ = True if not '__alias__' in attrs: new_class.__alias__ = None setattr(new_class, 'objects', classproperty(lambda *args, **kw: QuerySet(new_class))) return new_class
def validate_fields(self): for name, field in self._fields.items(): value = self.get_field_value(name) if field.required and field.is_empty(value): raise InvalidDocumentError("%s field '%s' is required." %\ (self.__class__.__name__, name)) try: is_valid = field.validate(value) except Exception as e: raise InvalidDocumentError( "%s field '%s' is invalid: %s" % (self.__class__.__name__, name, str(e))) if not is_valid: raise InvalidDocumentError("%s field '%s' must be valid." %\ (self.__class__.__name__, name)) return True
def sync_delete(self, session=None, **kwargs): """ 删除 :return: """ save_dict = self.result_2_dict() if '_id' not in save_dict.keys(): raise InvalidDocumentError('Not a valid database record.') result = self.get_sync_collection().delete_one( {'_id': ObjectId(save_dict.get('_id'))}, session=session, **kwargs) if result and result.deleted_count == 1: # 清除缓存 if self.__cached: CacheEngine.delete(getattr(self, 'oid')) return True return False
def __new__(cls, name, bases, attrs): flattened_bases = cls._get_bases(bases) super_new = super(DocumentMetaClass, cls).__new__ doc_fields = {} for base in flattened_bases[::-1]: if hasattr(base, '_fields'): doc_fields.update(base._fields) # Discover any document fields field_names = {} for field_name, doc_field in doc_fields.items(): field_names[doc_field.db_field] = field_names.get( doc_field.db_field, 0) + 1 for attr_name, attr_value in attrs.items(): if not isinstance(attr_value, BaseField): continue if attr_value.__class__.__name__ == 'DynamicField': continue attr_value.name = attr_name if not attr_value.db_field: attr_value.db_field = attr_name doc_fields[attr_name] = attr_value # Count names to ensure no db_field redefinitions field_names[attr_value.db_field] = field_names.get( attr_value.db_field, 0) + 1 # Set _fields and db_field maps attrs['_fields'] = doc_fields attrs['_db_field_map'] = { k: getattr(v, 'db_field', k) for k, v in doc_fields.items() } attrs['_fields_ordered'] = tuple(i[1] for i in sorted( (v.creation_counter, v.name) for v in doc_fields.values())) attrs['_reverse_db_field_map'] = { v: k for k, v in attrs['_db_field_map'].items() } new_class = super_new(cls, name, bases, attrs) new_class.__hierarchy__ = None new_class.__child_classes__ = [] if '__lazy__' not in attrs: new_class.__lazy__ = True if '__alias__' not in attrs: new_class.__alias__ = None if '__inherit__' not in attrs: new_class.__inherit__ = False if '__abstract__' not in attrs: new_class.__abstract__ = False if cls._is_base(flattened_bases): new_class.__abstract__ = True if '__collection__' not in attrs: new_class.__collection__ = cls._get_collection( new_class, flattened_bases) if new_class.__abstract__: new_class.__inherit__ = False new_class.__hierarchy__ = None new_class.__collection__ = None new_class.__child_classes__ = [] duplicate_db_fields = [k for k, v in field_names.items() if v > 1] if duplicate_db_fields: raise InvalidDocumentError( 'Multiple db_fields defined for: {}'.format( ', '.join(duplicate_db_fields))) if new_class.__inherit__: from motorengine.fields import StringField from motorengine.base import classes_registry cls._update_hierarchy(new_class, flattened_bases) if classes_registry.get(new_class.__hierarchy__): raise Exception('Model \'{}\' is already exists'.format( new_class.__hierarchy__)) # TODO: refactor this part classes_registry[new_class.__hierarchy__] = new_class _cls_field = StringField() _cls_field.name = _cls_field.db_field = '_cls' _cls_field.default = new_class.__hierarchy__ new_class._fields['_cls'] = _cls_field elif '_cls' in new_class._fields: del new_class._fields['_cls'] setattr( new_class, 'objects', classproperty(lambda *args, **kw: cls.query_set_class(new_class))) return new_class
def validate_fields(self): for name, field in self._fields.items(): if field.required and field.is_empty(self._values[field.db_field]): raise InvalidDocumentError("Field '%s' is required." % name) return True