Add a monkey patch to "
django.db.models.fields.files.FileDescriptor.__get__ (cf django bug #24823 https://code.djangoproject.com/ticket/24823)
This is done in order to avoid maintaining a django fork
--- a/.settings/org.eclipse.core.resources.prefs Fri Aug 28 18:04:30 2015 +0200
+++ b/.settings/org.eclipse.core.resources.prefs Tue Sep 01 18:27:47 2015 +0200
@@ -1,5 +1,6 @@
eclipse.preferences.version=1
encoding//src/ldt/ldt/api/ldt/tests/tests_project.py=utf-8
+encoding//src/ldt/ldt/apps.py=utf-8
encoding//src/ldt/ldt/indexation/backends/elasticsearch_backend.py=utf-8
encoding//src/ldt/ldt/indexation/highlighter.py=utf-8
encoding//src/ldt/ldt/indexation/models.py=utf-8
--- a/src/ldt/ldt/__init__.py Fri Aug 28 18:04:30 2015 +0200
+++ b/src/ldt/ldt/__init__.py Tue Sep 01 18:27:47 2015 +0200
@@ -1,6 +1,6 @@
-__all__ = ["VERSION", "get_version", "__version__"]
+__all__ = ["VERSION", "get_version", "__version__", "default_app_config"]
-VERSION = (1, 58, 0, "final", 0)
+VERSION = (1, 58, 1, "final", 0)
def get_version():
@@ -26,3 +26,5 @@
# TODO: remove this by reworking ldt dependencies
#from django.db.models.loading import get_models
#_ = get_models()
+
+default_app_config = 'ldt.apps.LdtAppConfig'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/apps.py Tue Sep 01 18:27:47 2015 +0200
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Sep 1, 2015
+
+@author: ymh
+'''
+
+from django.apps import AppConfig
+from django.core.files.base import File
+from django.db.models.fields.files import FieldFile
+from django.db.models.fields.files import FileDescriptor
+import six
+
+
+def ldt_get(self, instance=None, owner=None):
+ if instance is None:
+ raise AttributeError(
+ "The '%s' attribute can only be accessed from %s instances."
+ % (self.field.name, owner.__name__))
+
+ # This is slightly complicated, so worth an explanation.
+ # instance.file`needs to ultimately return some instance of `File`,
+ # probably a subclass. Additionally, this returned object needs to have
+ # the FieldFile API so that users can easily do things like
+ # instance.file.path and have that delegated to the file storage engine.
+ # Easy enough if we're strict about assignment in __set__, but if you
+ # peek below you can see that we're not. So depending on the current
+ # value of the field we have to dynamically construct some sort of
+ # "thing" to return.
+
+ # The instance dict contains whatever was originally assigned
+ # in __set__.
+ file = instance.__dict__[self.field.name] # @ReservedAssignment
+
+ # If this value is callable (certainly because the field was defined
+ # with a callable default), we execute the function and assign the
+ # result to the value
+ if six.callable(file):
+ file = file() # @ReservedAssignment
+ if isinstance(file, FieldFile) and not hasattr(file, 'field'):
+ instance.__dict__[self.field.name] = file
+
+ # If this value is a string (instance.file = "path/to/file") or None
+ # then we simply wrap it with the appropriate attribute class according
+ # to the file field. [This is FieldFile for FileFields and
+ # ImageFieldFile for ImageFields; it's also conceivable that user
+ # subclasses might also want to subclass the attribute class]. This
+ # object understands how to convert a path to a file, and also how to
+ # handle None.
+ if isinstance(file, six.string_types) or file is None:
+ attr = self.field.attr_class(instance, self.field, file)
+ instance.__dict__[self.field.name] = attr
+
+ # Other types of files may be assigned as well, but they need to have
+ # the FieldFile interface added to them. Thus, we wrap any other type of
+ # File inside a FieldFile (well, the field's attr_class, which is
+ # usually FieldFile).
+ elif isinstance(file, File) and not isinstance(file, FieldFile):
+ file_copy = self.field.attr_class(instance, self.field, file.name)
+ file_copy.file = file
+ file_copy._committed = False
+ instance.__dict__[self.field.name] = file_copy
+
+ # Finally, because of the (some would say boneheaded) way pickle works,
+ # the underlying FieldFile might not actually itself have an associated
+ # file. So we need to reset the details of the FieldFile in those cases.
+ elif isinstance(file, FieldFile) and not hasattr(file, 'field'):
+ file.instance = instance
+ file.field = self.field
+ file.storage = self.field.storage
+
+ # That was fun, wasn't it?
+ return instance.__dict__[self.field.name]
+
+class LdtAppConfig(AppConfig):
+ '''
+ App config to monkey patch django.db.models.fields.files.FileDescriptor.__get__ (cf django bug #24823 https://code.djangoproject.com/ticket/24823)
+ '''
+
+ name = 'ldt'
+ verbose_name = 'LDT Platform'
+
+ def ready(self):
+ FileDescriptor.__get__ = ldt_get