Skip to content

Commit fc897ca

Browse files
committed
Merge pull request #2 from feliperyan/master
LocalStorageFileField - thanks @feliperyan
2 parents 42f8070 + ed4db79 commit fc897ca

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

fields/fields.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
from datetime import timedelta
22
from mongoengine.base import BaseField
33

4+
import os
5+
import datetime
6+
7+
from mongoengine.python_support import str_types
8+
from django.db.models.fields.files import FieldFile
9+
from django.core.files.base import File
10+
from django.core.files.storage import default_storage
11+
12+
from mongoengine.connection import get_db, DEFAULT_CONNECTION_NAME
13+
from django.utils.encoding import force_text
14+
15+
416
class TimedeltaField(BaseField):
517
"""A timedelta field.
618
@@ -38,3 +50,83 @@ def total_seconds(value):
3850
return (value.days * 24 * 3600) + \
3951
(value.seconds) + \
4052
(value.microseconds / 1000000.0)
53+
54+
55+
class LocalStorageFileField(BaseField):
56+
57+
proxy_class = FieldFile
58+
59+
def __init__(self,
60+
db_alias=DEFAULT_CONNECTION_NAME,
61+
name=None,
62+
upload_to='',
63+
storage=None,
64+
**kwargs):
65+
66+
self.db_alias = db_alias
67+
self.storage = storage or default_storage
68+
self.upload_to = upload_to
69+
70+
if callable(upload_to):
71+
self.generate_filename = upload_to
72+
73+
super(DJFileField, self).__init__(**kwargs)
74+
75+
76+
def __get__(self, instance, owner):
77+
# Lots of information on whats going on here can be found
78+
# on Django's FieldFile implementation, go over to GitHub to
79+
# read it.
80+
file = instance._data.get(self.name)
81+
82+
if isinstance(file, str_types) or file is None:
83+
attr = self.proxy_class(instance, self, file)
84+
instance._data[self.name] = attr
85+
86+
elif isinstance(file, File) and not isinstance(file, FieldFile):
87+
file_copy = self.proxy_class(instance, self, file.name)
88+
file_copy.file = file
89+
file_copy._committed = False
90+
instance._data[self.name] = file_copy
91+
92+
elif isinstance(file, FieldFile) and not hasattr(file, 'field'):
93+
file.instance = instance
94+
file.field = self
95+
file.storage = self.storage
96+
97+
return instance._data[self.name]
98+
99+
100+
def __set__(self, instance, value):
101+
instance._data[self.name] = value
102+
103+
104+
def get_directory_name(self):
105+
return os.path.normpath(force_text(datetime.datetime.now().strftime(self.upload_to)))
106+
107+
108+
def get_filename(self, filename):
109+
return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
110+
111+
112+
def generate_filename(self, instance, filename):
113+
return os.path.join(self.get_directory_name(), self.get_filename(filename))
114+
115+
116+
def to_mongo(self, value):
117+
# Store the path in MongoDB
118+
# I also used this bit to actually save the file to disk.
119+
# The value I'm getting here is a FileFiled and it all looks ok.
120+
121+
if not value._committed and value is not None:
122+
value.save(value.name, value)
123+
return value.path
124+
125+
return value.name
126+
127+
128+
def to_python(self, value):
129+
eu = self
130+
return eu.proxy_class(eu.owner_document, eu, value)
131+
132+

0 commit comments

Comments
 (0)