示例#1
0
	def __getattr__( self, name ):
		if name not in self._values and self._is_lazy and \
			'_id' in self._data and self._data['_id'] is not None:

			if name not in self._fields:
				raise AttributeError

			# field is being accessed and the object is currently in lazy mode
			# may need to retrieve rest of document
			field = self._fields[name]
			if field.dbField not in self._data:
				# field not retrieved from database! load whole document. weeee
				result = connection.getDatabase( )[self._collection].find_one( { '_id': self._data['_id'] } )
				if result is None:
					raise self.DoesNotExist
				self._fromMongo( result, overwrite=False )
				
				self._is_lazy = False
		
		field = self._fields.get( name, None )

		if not name in self._values:
			default = None
			if field is not None:
				default = field.getDefault( )

			self._values[name] = default
		
		value = self._values.get( name )
		
		return value
示例#2
0
	def __get__( self, instance, owner ):
		if instance is not None:
			# Document class being accessed, not an object
			return self
		
		if self.collection is None:
			database = getDatabase( )
			self.collection = database[owner._collection]
		
		return QuerySet( owner, self.collection )
示例#3
0
	def __get__( self, instance, owner ):
		if instance is not None:
			# Document class being accessed, not an object
			return self
		
		# this should be fast, it's just a thin wrapper to get a collection?
		groupName = getattr(owner, 'database_group', 'default')
		database = getDatabase( groupName )
		self.collection = database[owner._collection]
		
		return QuerySet( owner, self.collection )
示例#4
0
    def save(self, forceInsert=False, safe=True):
        database = getDatabase()
        collection = database[self._collection]

        self._resyncFromPython()

        if "_id" in self._data and self._data["_id"] is None:
            del self._data["_id"]
        try:
            if forceInsert:
                newId = collection.insert(self._data, safe=safe)
            else:
                newId = collection.save(self._data, safe=safe)
        except pymongo.errors.OperationFailure, err:
            message = "Could not save document (%s)"
            if u"duplicate key" in unicode(err):
                message = u"Tried to save duplicate unique keys (%s)"
            raise OperationError(message % unicode(err))
示例#5
0
	def save( self, forceInsert=False, **kwargs ):
		database = getDatabase( )
		collection = database[self._collection]
		
		self._resyncFromPython( )
		
		if '_id' in self._data and self._data['_id'] is None:
			del self._data['_id']
		try:
			if forceInsert:
				newId = collection.insert( self._data, **kwargs )
			else:
				newId = collection.save( self._data, **kwargs )
		except pymongo.errors.OperationFailure, err:
			message = 'Could not save document (%s)'
			if u'duplicate key' in unicode(err):
				message = u'Tried to save duplicate unique keys (%s)'
			raise OperationError( message % unicode(err) )
示例#6
0
	def __new__( cls, name, bases, attrs ):
		if DocumentRegistry.hasDocument( name ):
			return DocumentRegistry.getDocument( name )
			
		# don't do anything if we're the class that defines the metaclass
		#metaclass = attrs.get( '__metaclass__' )
		superNew = super(DocumentMetaclass, cls).__new__
		#if metaclass and issubclass(metaclass, DocumentMetaclass):
		#	return superNew( cls, name, bases, attrs )
		
		fields = {}
		collection = name.lower()
		needsPrimaryKey = False
		primaryKey = None
		
		# find all inherited fields and record them
		for base in bases:
			if hasattr(base, '_fields'):
				fields.update( base._fields )
			if hasattr(base, '_collection'):
				collection = base._collection
			if hasattr(base, '__needs_primary_key__'):
				needsPrimaryKey = True
		
		if not '__internal__' in attrs:
			attrs['_collection'] = collection
		
		# find all fields and add them to our field list
		for attrName, attrValue in attrs.items( ):
			if hasattr(attrValue, '__class__') and \
				issubclass(attrValue.__class__, BaseField):
				field = attrValue
				field.name = attrName
				if not hasattr(field, 'dbField') or field.dbField is None:
					field.dbField = attrName
				fields[attrName] = field
				del attrs[attrName]
		
		for field,value in fields.iteritems( ):
			if value.primaryKey:
				assert primaryKey is None, "Can only have one primary key per document"
				primaryKey = field
		
		# add a primary key if none exists and one is required
		if needsPrimaryKey and primaryKey is None:
			fields['id'] = ObjectIdField( primaryKey=True, dbField='_id' )
			primaryKey = 'id'
		
		attrs['_primaryKeyField'] = primaryKey
		
		# make sure we have all indexes that are specified
		if 'meta' in attrs:
			meta = attrs['meta']
			if 'indexes' in meta:
				indexes = meta['indexes']
				
				_database = getDatabase( )
				_collection = _database[collection]
				
				for index in indexes:
					if not isinstance(index, (list,tuple)):
						index = [index]
					def indexConverter( fieldName ):
						if fieldName in fields:
							return fields[fieldName].optimalIndex( )
						return fieldName
					pyMongoIndexKeys = sortListToPyMongo( index, indexConverter )
					_collection.ensure_index( pyMongoIndexKeys )
		
		# add a query set manager if none exists already
		if 'objects' not in attrs:
			attrs['objects'] = QuerySetManager( )
		
		# construct the new class
		attrs['_is_lazy'] = False
		attrs['_fields'] = fields
		attrs['_data'] = None
		attrs['_values'] = None
		newClass = superNew( cls, name, bases, attrs )
		
		# record the document in the fields
		for field in newClass._fields.values( ):
			#field.ownerDocument = newClass
			field.setOwnerDocument( newClass )
		
		# add DoesNotExist and MultipleObjectsReturned exceptions
		module = attrs.get('__module__')
		newClass._addException( 'DoesNotExist', bases,
								defaultBase=DoesNotExist,
								module=module )
		newClass._addException( 'MultipleObjectsReturned', bases,
								defaultBase=MultipleObjectsReturned,
								module=module )
		
		# register the document for name-based reference
		DocumentRegistry.registerDocument( name, newClass )
		
		return newClass