Add a monkey patch to " V01.58.01
authorymh <ymh.work@gmail.com>
Tue, 01 Sep 2015 18:27:47 +0200
changeset 1420 0637048db5d4
parent 1419 3880aba1b2b1
child 1421 dc3c9a705d6d
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
.settings/org.eclipse.core.resources.prefs
src/ldt/ldt/__init__.py
src/ldt/ldt/apps.py
--- 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