Added a Django storage backend.

- New GridFSStorage storage backend
- New FileDocument document for storing files in GridFS
- Whitespace cleaned up in various files
This commit is contained in:
Steve Challis
2010-09-29 23:36:58 +01:00
parent bd1bf9ba24
commit b5eb3ea1cd
9 changed files with 248 additions and 91 deletions

View File

@@ -16,11 +16,7 @@ __all__ = ['StringField', 'IntField', 'FloatField', 'BooleanField',
'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField',
'ObjectIdField', 'ReferenceField', 'ValidationError',
'DecimalField', 'URLField', 'GenericReferenceField', 'FileField',
<<<<<<< HEAD
'BinaryField', 'SortedListField', 'EmailField', 'GeoLocationField']
=======
'BinaryField', 'SortedListField', 'EmailField', 'GeoPointField']
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
RECURSIVE_REFERENCE_CONSTANT = 'self'
@@ -42,7 +38,7 @@ class StringField(BaseField):
if self.max_length is not None and len(value) > self.max_length:
raise ValidationError('String value is too long')
if self.min_length is not None and len(value) < self.min_length:
raise ValidationError('String value is too short')
@@ -350,7 +346,8 @@ class SortedListField(ListField):
def to_mongo(self, value):
if self._ordering is not None:
return sorted([self.field.to_mongo(item) for item in value], key=itemgetter(self._ordering))
return sorted([self.field.to_mongo(item) for item in value],
key=itemgetter(self._ordering))
return sorted([self.field.to_mongo(item) for item in value])
class DictField(BaseField):
@@ -514,25 +511,17 @@ class BinaryField(BaseField):
if self.max_bytes is not None and len(value) > self.max_bytes:
raise ValidationError('Binary value is too long')
<<<<<<< HEAD
=======
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
class GridFSProxy(object):
"""Proxy object to handle writing and reading of files to and from GridFS
.. versionadded:: 0.4
"""
<<<<<<< HEAD
def __init__(self):
self.fs = gridfs.GridFS(_get_db()) # Filesystem instance
self.newfile = None # Used for partial writes
self.grid_id = None # Store GridFS id for file
=======
def __init__(self, grid_id=None):
self.fs = gridfs.GridFS(_get_db()) # Filesystem instance
self.newfile = None # Used for partial writes
self.grid_id = grid_id # Store GridFS id for file
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
def __getattr__(self, name):
obj = self.get()
@@ -543,17 +532,13 @@ class GridFSProxy(object):
return self
def get(self, id=None):
<<<<<<< HEAD
try: return self.fs.get(id or self.grid_id)
except: return None # File has been deleted
=======
if id:
self.grid_id = id
try:
return self.fs.get(id or self.grid_id)
except:
return None # File has been deleted
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
# File has been deleted
return None
def new_file(self, **kwargs):
self.newfile = self.fs.new_file(**kwargs)
@@ -575,20 +560,19 @@ class GridFSProxy(object):
self.newfile.writelines(lines)
def read(self):
<<<<<<< HEAD
try: return self.get().read()
except: return None
=======
try:
return self.get().read()
except:
return None
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
def delete(self):
# Delete file from GridFS, FileField still remains
self.fs.delete(self.grid_id)
self.grid_id = None
#self.grid_id = None
# Doesn't make a difference because will be put back in when
# reinstantiated We should delete all the metadata stored with the
# file too
def replace(self, file, **kwargs):
self.delete()
@@ -601,41 +585,30 @@ class GridFSProxy(object):
msg = "The close() method is only necessary after calling write()"
warnings.warn(msg)
<<<<<<< HEAD
=======
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
class FileField(BaseField):
"""A GridFS storage field.
.. versionadded:: 0.4
"""
def __init__(self, **kwargs):
<<<<<<< HEAD
self.gridfs = GridFSProxy()
=======
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
super(FileField, self).__init__(**kwargs)
def __get__(self, instance, owner):
if instance is None:
return self
<<<<<<< HEAD
return self.gridfs
=======
# Check if a file already exists for this model
grid_file = instance._data.get(self.name)
if grid_file:
return grid_file
self.grid_file = grid_file
if self.grid_file:
return self.grid_file
return GridFSProxy()
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
def __set__(self, instance, value):
if isinstance(value, file) or isinstance(value, str):
# using "FileField() = file/string" notation
<<<<<<< HEAD
self.gridfs.put(value)
=======
grid_file = instance._data.get(self.name)
# If a file already exists, delete it
if grid_file:
@@ -649,24 +622,11 @@ class FileField(BaseField):
# Create a new proxy object as we don't already have one
instance._data[self.name] = GridFSProxy()
instance._data[self.name].put(value)
>>>>>>> 32e66b29f44f3015be099851201241caee92054f
else:
instance._data[self.name] = value
def to_mongo(self, value):
# Store the GridFS file id in MongoDB
<<<<<<< HEAD
return self.gridfs.grid_id
def to_python(self, value):
# Use stored value (id) to lookup file in GridFS
return self.gridfs.get()
def validate(self, value):
assert isinstance(value, GridFSProxy)
assert isinstance(value.grid_id, pymongo.objectid.ObjectId)
=======
if isinstance(value, GridFSProxy) and value.grid_id is not None:
return value.grid_id
return None
@@ -680,6 +640,7 @@ class FileField(BaseField):
assert isinstance(value, GridFSProxy)
assert isinstance(value.grid_id, pymongo.objectid.ObjectId)
class GeoPointField(BaseField):
"""A list storing a latitude and longitude.
"""
@@ -692,10 +653,9 @@ class GeoPointField(BaseField):
if not isinstance(value, (list, tuple)):
raise ValidationError('GeoPointField can only accept tuples or '
'lists of (x, y)')
if not len(value) == 2:
raise ValidationError('Value must be a two-dimensional point.')
if (not isinstance(value[0], (float, int)) and
not isinstance(value[1], (float, int))):
raise ValidationError('Both values in point must be float or int.')
>>>>>>> 32e66b29f44f3015be099851201241caee92054f