Mongoengine stores FileField and ImageField to GridFS. What's the easiest approach to replicate the functionality of the original File/Image Field?
EDIT:
So this is the class I have in place at the moment. I'm able to load files and save them to disk, Mongo holds the path to the file in database.
I'm falling over on "to_python" as I believe it needs to create an object of the proxy_class but I can't see how, if all I'm getting is a path to the file (as the value passed in).
import os
import datetime
from mongoengine.python_support import str_types
from django.db.models.fields.files import FieldFile
from django.core.files.base import File
from django.core.files.storage import default_storage
from mongoengine.base import BaseField
from mongoengine.connection import get_db, DEFAULT_CONNECTION_NAME
from django.utils.encoding import force_text
#from django.utils.encoding import force_str
class DJFileField(BaseField):
    proxy_class = FieldFile
    def __init__(self,
                 db_alias=DEFAULT_CONNECTION_NAME, 
                 name=None,
                 upload_to='',
                 storage=None,
                 **kwargs):
        self.db_alias = db_alias
        self.storage = storage or default_storage
        self.upload_to = upload_to
        if callable(upload_to):
            self.generate_filename = upload_to
        super(DJFileField, self).__init__(**kwargs)
    def __get__(self, instance, owner):
        # Lots of information on whats going on here can be found
        # on Django's FieldFile implementation, go over to GitHub to
        # read it.
        file = instance._data.get(self.name)
        if isinstance(file, str_types) or file is None:
            attr = self.proxy_class(instance, self, file)
            instance._data[self.name] = attr
        elif isinstance(file, File) and not isinstance(file, FieldFile):
            file_copy = self.proxy_class(instance, self, file.name)
            file_copy.file = file
            file_copy._committed = False
            instance._data[self.name] = file_copy
        elif isinstance(file, FieldFile) and not hasattr(file, 'field'):
            file.instance = instance
            file.field = self
            file.storage = self.storage
        # That was fun, wasn't it?
        return instance._data[self.name]
    def __set__(self, instance, value):
        instance._data[self.name] = value
    # The 3 methods below get used by the FieldFile proxy_object
    def get_directory_name(self):
        return os.path.normpath(force_text(datetime.datetime.now().strftime(self.upload_to)))
    def get_filename(self, filename):
        return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
    def generate_filename(self, instance, filename):
        return os.path.join(self.get_directory_name(), self.get_filename(filename))
    def to_mongo(self, value):
    # Store the path in MongoDB
    # I also used this bit to actually save the file to disk.
    # The value I'm getting here is a FileFiled and it all looks
    # pretty good at this stage even though I'm not 100% sure
    # of what's going on.
        import ipdb; ipdb.set_trace()
        if not value._committed and value is not None:
            value.save(value.name, value)
            return value.path
        return value.path    
    def to_python(self, value):
        # Now this is the real problem, value is the path that got saved
        # in mongo. No idea how to return a FileField obj from here.
        # self.instance and instance throw errors.
                I think it would be a good addition - maybe called LocalFileField to make it more framework agnostic and if you provided tests and docs it would make a great addition to https://github.com/MongoEngine/extras-mongoengine
The only reason I'm not sold on having it in core - is if you are running a replicaset the file would still only be stored on one node.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With