Python Django-无法为具有动态上载到值的ImageField创建迁移
我刚刚将我的应用升级到1.7(实际上还在尝试) 这是我在models.py中的内容:Python Django-无法为具有动态上载到值的ImageField创建迁移,python,django,django-migrations,Python,Django,Django Migrations,我刚刚将我的应用升级到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) # ret
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.
我不确定是否可以回答我自己的问题,但我只是想出来了(我想) 根据,我编辑了我的代码:
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")
这对我很有效。我也有同样的问题,但我的模型中有很多图像文件
head = ImageField(upload_to=upload_to("head")
icon = ImageField(upload_to=upload_to("icon")
...etc
我不想为我拥有的每个ImageField列创建upload_to wraper func
所以我只需要创建一个名为wrapper的func,它就可以工作了
def wrapper():
return
我认为它可以正常工作,因为我打开了迁移文件,发现:
('head', models.ImageField(upload_to=wrapper)),
我想这不会影响迁移过程您可以使用kwargs创建如下函数:
def upload_image_location(instance, filename, thumbnail=False):
name, ext = os.path.splitext(filename)
path = f'news/{instance.slug}{f"_thumbnail" if thumbnail else ""}{ext}'
n = 1
while os.path.exists(path):
path = f'news/{instance.slug}-{n}{ext}'
n += 1
return path
class Migration(migrations.Migration):
dependencies = [
('news', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='news',
name='thumbnail_image',
field=models.ImageField(blank=True, upload_to=functools.partial(news.models.upload_image_location, *(), **{'thumbnail': True})),
),
migrations.AlterField(
model_name='news',
name='image',
field=models.ImageField(height_field='image_height', upload_to=news.models.upload_image_location, width_field='image_width'),
),
]
并在模型中使用此方法:
image = models.ImageField(
upload_to=upload_image_location,
width_field='image_width',
height_field='image_height'
)
thumbnail_image = models.ImageField(upload_to=partial(upload_image_location, thumbnail=True), blank=True)
您将得到如下迁移:
def upload_image_location(instance, filename, thumbnail=False):
name, ext = os.path.splitext(filename)
path = f'news/{instance.slug}{f"_thumbnail" if thumbnail else ""}{ext}'
n = 1
while os.path.exists(path):
path = f'news/{instance.slug}-{n}{ext}'
n += 1
return path
class Migration(migrations.Migration):
dependencies = [
('news', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='news',
name='thumbnail_image',
field=models.ImageField(blank=True, upload_to=functools.partial(news.models.upload_image_location, *(), **{'thumbnail': True})),
),
migrations.AlterField(
model_name='news',
name='image',
field=models.ImageField(height_field='image_height', upload_to=news.models.upload_image_location, width_field='image_width'),
),
]
是否可以使用此选项,并为每个字段添加自定义文件路径?@Garreth00是,将文件路径作为参数传递给
PathAndRename
class。比如:custom\u path=pathandename(“/profiles/bg images”)
这是一个很好的答案!工作完美无瑕。谢谢@知识产权。有错误吗?因为我两天前在另一个项目中使用了完全相同的代码。不管我用普通的方法还是解构的方法,效果都很好