我们使用可调用的方式动态生成项目中的upload_to目标,如下所示。
class PKUploader(object):
def __init__(self, prefix, extension=None):
self.prefix = prefix
self.extension = extension
def __call__(self, instance, filename):
ext = self.extension or os.path.splitext(filename)[1]
if not ext.startswith('.'):
ext = '.' + ext
if instance.pk is None:
pk = random.randint(1000, 99999)
else:
pk = instance.pk
pk = str(pk) + str(uuid.uuid4())
return '{}/{}{}'.format(self.prefix, pk, ext)
在我们的模型中,它像
一样使用class CoolKids(models.Model):
image = models.ImageField(upload_to=PKUploader('users_image'))
但是,当我们从django 1.6升级到1.7并运行makemigrations时,我们会收到以下错误。
ValueError: Cannot serialize: <PKUploader object at 0x7ff5f1cf0b90>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing
任何人都可以对此有所了解吗?
答案 0 :(得分:2)
要序列化任意类的实例,您需要实现deconstruct()
方法:
class PKUploader(object):
def __init__(self, prefix, extension=None):
self.prefix = prefix
self.extension = extension
def deconstruct(self):
kwargs = {'prefix': self.prefix}
if self.extension is not None:
kwargs['extension'] = self.extension
return 'import.path.to.PKUploader', (), kwargs
def __call__(self, instance, filename):
...
通过返回类的导入路径以及位置和关键字初始化参数,Django可以将此信息序列化为重新创建原始实例的有效python代码。
为简化此操作,您可以使用@deconstructible
装饰器:
from django.utils.deconstruct import deconstructible
@deconstructible
class PKUploader(object):
...
有关详细信息,请参阅documentation。
答案 1 :(得分:0)
如果将callable分配给变量,则应该避免此错误。
upload_to = PKUploader('users_image')
class CoolKids(models.Model):
image = models.ImageField(upload_to=upload_to)