无法摆脱 Django ImageField 中的 FileNotFoundError

问题描述 投票:0回答:1

我有一个 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 来执行循环。

有什么想法吗?

python django exception django-models
1个回答
0
投票

这影响了我,因为我将

image_width
image_height
字段添加到具有现有文件的旧数据库中,其中一些现已删除。

我刚才所做的解决方法是使用数据库中的任意非零值手动填充宽度和高度值。

这是我写的一个管理命令

  1. 使用占位符值填充所有非零条目
  2. 用真实值替换每个占位符值(通过保存)

这个结构允许我在步骤 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!"))

© www.soinside.com 2019 - 2024. All rights reserved.