Skip to content

Commit 69f585b

Browse files
authored
Merge pull request #297 from mihalikv/develop
Added ability to pickle FilePreference in Django 4.2
2 parents 3007198 + eb79367 commit 69f585b

File tree

2 files changed

+39
-26
lines changed

2 files changed

+39
-26
lines changed

dynamic_preferences/serializers.py

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,28 @@ def to_python(self, value, **kwargs):
275275
raise self.exception("Array {0} cannot be converted to int".format(value))
276276

277277

278+
# FieldFile also needs a model instance to save changes.
279+
class FakeInstance(object):
280+
"""
281+
FieldFile needs a model instance to update when file is persisted
282+
or deleted
283+
"""
284+
285+
def save(self):
286+
return
287+
288+
289+
class FakeField(object):
290+
"""
291+
FieldFile needs a field object to generate a filename, persist
292+
and delete files, so we are effectively mocking that.
293+
"""
294+
295+
name = "noop"
296+
attname = "noop"
297+
max_length = 10000
298+
299+
278300
class PreferenceFieldFile(FieldFile):
279301
"""
280302
In order to have the same API that we have with models.FileField,
@@ -285,33 +307,9 @@ class PreferenceFieldFile(FieldFile):
285307

286308
def __init__(self, preference, storage, name):
287309
super(FieldFile, self).__init__(None, name)
288-
289-
# FieldFile also needs a model instance to save changes.
290-
class FakeInstance(object):
291-
"""
292-
FieldFile needs a model instance to update when file is persisted
293-
or deleted
294-
"""
295-
296-
def save(self):
297-
return
298-
299310
self.instance = FakeInstance()
300-
301-
class FakeField(object):
302-
"""
303-
FieldFile needs a field object to generate a filename, persist
304-
and delete files, so we are effectively mocking that.
305-
"""
306-
307-
name = "noop"
308-
attname = "noop"
309-
max_length = 10000
310-
311-
def generate_filename(field, instance, name):
312-
return os.path.join(self.preference.get_upload_path(), f.name)
313-
314311
self.field = FakeField()
312+
self.field.storage = storage
315313
self.storage = storage
316314
self._committed = True
317315
self.preference = preference
@@ -483,5 +481,5 @@ def to_python(cls, value, **kwargs):
483481
while "" in ret:
484482
pos = ret.index("")
485483
val = ret[pos - 1] + cls.separator + ret[pos + 1]
486-
ret = ret[0 : pos - 1] + [val] + ret[pos + 2 :]
484+
ret = ret[0: pos - 1] + [val] + ret[pos + 2:]
487485
return ret

tests/test_types.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import os
22
import decimal
3+
import pickle
4+
35
import pytest
46

57
from datetime import date, timedelta, datetime, time
@@ -239,6 +241,19 @@ def test_file_preference_api_repr_returns_path(db):
239241
assert p.api_repr(f) == f.url
240242

241243

244+
def test_file_preference_if_pickleable(db):
245+
manager = global_preferences_registry.manager()
246+
f = SimpleUploadedFile(
247+
"test_file_24485a80-8db9-4191-ae49-da7fe2013794.txt",
248+
"hello world".encode("utf-8"),
249+
)
250+
try:
251+
manager["blog__logo"] = f
252+
pickle.dumps(manager["blog__logo"])
253+
except Exception:
254+
pytest.fail("FilePreference not pickleable")
255+
256+
242257
def test_choice_preference(fake_user):
243258
fake_user.preferences["user__favorite_vegetable"] = "C"
244259
assert fake_user.preferences["user__favorite_vegetable"] == "C"

0 commit comments

Comments
 (0)