我有一个 django 模型产品,它有一个图像字段
class Product(BaseProduct):
img_height = models.PositiveIntegerField(editable=False, null=True, blank=True)
img_width = models.PositiveIntegerField(editable=False, null=True, blank=True)
file = models.ImageField('Image', upload_to=product_img_path,
height_field='img_height', width_field='img_width',
null=True, blank=True, max_length=255)
现在因为我从 Excel 文件加载了超过 15,000 条记录的产品,所以很少有文件字段中的图像路径实际上不存在于我的目录中。
这会导致我的代码每次尝试
FileNotFoundError
时都会引发 for product in Product.objects.all()
,然后我才能用 try-except
块捕获错误。
我希望进行一次迭代,可以检查文件是否存在,并将文件字段设置为空,以获取包含不存在文件的记录。
但是这是不可能的,因为一旦我尝试调用艺术品的实例或创建迭代,就会引发错误。
所以下面的代码:
products = Product.objects.all()
for product in products:
try:
if product.file:
pass
except FileNotFoundError:
product.file = None
product.save()
引发的错误:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\user\\project\\media\\products\\blahblah.jpeg'
并且堆栈跟踪显示错误是从迭代行引发的for product in products:
我尝试遵循此线程,但没有任何运气:当文件不存在时,如何避免 django 模型 ImageField 中的 FileNotFound 错误
开发已经取得进展,所以我不需要将字段类型更改为 char 来执行循环。
有什么想法吗?
这影响了我,因为我将
image_width
和 image_height
字段添加到具有现有文件的旧数据库中,其中一些现已删除。
我刚才所做的解决方法是使用数据库中的任意非零值手动填充宽度和高度值。
这是我写的一个管理命令:
这个结构允许我在步骤 2 中插入一个 try/catch 块,以忽略文件系统上丢失文件的那些条目。
# myapp/management/commands/resave_stills.py
from django.core.management.base import BaseCommand
from myapp.models import Still
"""
Run with:
python manage.py resave_stills
"""
class Command(BaseCommand):
help = "Re-saves all still objects that have heights or widths of 0, or 16x9"
def handle(self, *args, **options):
# Step 1: Populate all non-zero entries with a placeholder value
stills = Still.objects.all().order_by("-id")
stills = stills.exclude(image_width__gt=0)
stills = stills.exclude(image_height__gt=0)
self.stdout.write(
self.style.SUCCESS("About to set %s stills to be 16x9" % stills.count())
)
stills.update(image_width=16)
stills.update(image_height=9)
# Step 2: Replace each placeholder value with the true value by saving it
stills = Still.objects.all().order_by("-id")
stills = stills.exclude(image_width__gt=16)
stills = stills.exclude(image_height__gt=9)
self.stdout.write(
self.style.SUCCESS(
"About to iterate over %s stills to find their true resolution..."
% stills.count()
)
)
stills = stills.iterator()
for still in stills:
try:
still.save()
self.stdout.write(
self.style.SUCCESS("Successfully saved still %s" % still.id)
)
except FileNotFoundError as e:
self.stdout.write(self.style.WARNING(f"Unable to save still: {e}"))
self.stdout.write(self.style.SUCCESS("Finished!"))