Django - невозможно создать миграции для ImageField с динамическим значением upload_to
Я только что обновил свое приложение до 1.7 (на самом деле все еще пытаюсь).
Это то, что я имел в models.py:
def path_and_rename(path):
def wrapper(instance, filename):
ext = filename.split('.')[-1]
# set filename as random string
filename = '{}.{}'.format(uuid4().hex, ext)
# return the whole path to the file
return os.path.join(path, filename)
return wrapper
class UserProfile(AbstractUser):
#...
avatar = models.ImageField(upload_to=path_and_rename("avatars/"),
null=True, blank=True,
default="avatars/none/default.png",
height_field="image_height",
width_field="image_width")
Когда я пытаюсь makemigrations
, он бросает:
ValueError: Could not find function wrapper in webapp.models.
Please note that due to Python 2 limitations, you cannot serialize unbound method functions (e.g. a method declared
and used in the same class body). Please move the function into the main module body to use migrations.
Ответы
Ответ 1
Я не уверен, нормально ли отвечать на мой вопрос, но я просто понял (думаю).
В соответствии с этот отчет об ошибке, я редактировал свой код:
from django.utils.deconstruct import deconstructible
@deconstructible
class PathAndRename(object):
def __init__(self, sub_path):
self.path = sub_path
def __call__(self, instance, filename):
ext = filename.split('.')[-1]
# set filename as random string
filename = '{}.{}'.format(uuid4().hex, ext)
# return the whole path to the file
return os.path.join(self.path, filename)
path_and_rename = PathAndRename("/avatars")
И затем, в определении поля:
avatar = models.ImageField(upload_to=path_and_rename,
null=True, blank=True,
default="avatars/none/default.png",
height_field="image_height",
width_field="image_width")
Это сработало для меня.
Ответ 2
У меня была такая же проблема, но у меня много ImageFile в моих моделях
head = ImageField(upload_to=upload_to("head")
icon = ImageField(upload_to=upload_to("icon")
...etc
Я не хочу создавать upload_to wraper func для каждого столбца ImageField, который у меня есть.
Итак, я просто создаю func с именем wrapper, и он woks
def wrapper():
return
Я думаю, что это работает отлично, потому что я открыл файл миграции, и я нашел это:
('head', models.ImageField(upload_to=wrapper)),
Я предполагаю, что это не влияет на процесс миграции