gpt4 book ai didi

python - 如何以编程方式上传本地文件作为 Django 模型字段?

转载 作者:行者123 更新时间:2023-12-01 06:36:44 25 4
gpt4 key购买 nike

我在尝试从本地路径将文件上传到 FileField 时遇到问题。

我已在 S3 存储桶中正确配置了 CDN 后端,并将其用作我的模型字段之一的 PrivateMediaStorage:

class MyModel(models.Model):
some_file = models.FileField(storage=PrivateMediaStorage())
...

通过这个非常简单的配置,每当我通过 django-admin 创建/更新模型时,它都会被保存,并且附加为 some_file 的文件会正确上传到 S3 桶。

但是,如果我尝试以编程方式创建/更新模型实例,例如通过自定义 manage.py 命令,则会创建模型实例本身,但附件永远不会上传到 CDN。这是我用来上传文件的代码的简化版本:

class Command(BaseCommand):
help = 'Creates dummy instance for quicker configuration'

def handle(self, *args, **options):
some_file = os.path.join(os.path.dirname(__file__), '../../../temporary/some_image.png')

if not os.path.exists(some_file):
raise CommandError(f'File {some_file} does not exist')
else:
instance, created = MyModel.objects.get_or_create(defaults={'some_file': some_file}, ...)

我的实现中缺少什么以及需要调整什么才能允许从本地存储上传文件?

最佳答案

您正在将一个字符串(os.path.join() 的结果)传递到您的 some_file 字段,但您需要向它传递一个实际的 File 对象.

直接在模型上保存文件的最简单方法是使用 FieldFile's save() 方法。

作为所提供案例的可行解决方案,创建记录的有效方法是:

instance = MyModel.objects.create(some_file=File(file=open(some_file, 'rb'), name='some_name.png'))

或者甚至更好地使用pathlib动态获取名称:

from pathlib import Path

instance = MyModel.objects.create(some_file=File(file=open(some_file, 'rb'), name=Path(some_file).name))

请注意,根据文件获取行不太可能起作用,据我所知,每次打开文件时,都会使用 File 实例作为参数执行 get_or_create()可能每次都会创建一个新行。最好将文件字段放入默认值:

with open(some_file, 'rb') as file:
instance, created = MyModel.objects.get_or_create(
some_other_field=...,
defaults={'some_file': File(
file=file,
name=pathlib.Path(some_file).name
)}
)

关于python - 如何以编程方式上传本地文件作为 Django 模型字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59629873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com