首页 > 解决方案 > Django 更快地从 URL 本地存储图像的方法?

问题描述

我正在一个网站上工作,我想从外部 API 填充产品数据。这个api有数百个产品数据,每个产品都有几十个变体。每个产品和数据都有它们的图像,我使用模型中的 Django 的 ImageField 存储在本地。现在的问题是有超过 15000 张图像,并且填充图像数据需要很长时间。API的结构如下:

{
...
Single Product Image: ...
    { Product Variant1: ..., [list of 4 images] }
    { Product Variant2: ..., [list of 4 images] }
    { Product Variant3: ..., [list of 4 images] }
}

每个产品都有 10-50 种变化。这是我所做的。对于变体图像,我使用多对一关系表来存储每个变体的所有图像:

模型.py:

class ProductsVariation(models.Model):
    ....

class VariationImages(models.Model):
    prd_id = models.ForeignKey(ProductsVariation, on_delete=models.CASCADE)
    img = models.ImageField(
        upload_to=settings.MEDIA_ROOT + 'product_variation')

get_products.py:

from django.core.files import File
from tempfile import NamedTemporaryFile
import requests

for product in api_data: #Loop over main product
    ...
    main_product_request = requests.get(product['IMAGE_NAME'])

    main_img_temp = NamedTemporaryFile(delete=True)
    main_img_temp.write(main_product_request.content)
    main_img_temp.flush()

    main_product.prd_img.save(product['GENERIC_NAME'] + ".jpg", File(main_img_temp), save=True)
    main_product.save()
    # Populate this product's variants
    for variants in product['Product']: # Loop through each variant of this product
        ....
        for img in variants['Images']: # For each variant, save their images to DB
            vari = VariationImages.objects.create(prd_id=prd_variant)

            vari_product_request = requests.get(img)

            vari_img_temp = NamedTemporaryFile(delete=True)
            vari_img_temp.write(vari_product_request.content)
            vari_img_temp.flush()

            vari.img.save(product['GENERIC_NAME'] + ".jpg", File(vari_img_temp), save=True)
            vari.save()

澄清一下,main_product 图像和变体图像位于数据库中的单独表中。我找不到任何其他方式来存储图像。也许有更好的方法从 API 存储图像?或者也许这是我如何做的问题?我不知道如何优化这个。

编辑:经过更多测试,我很确定瓶颈来自保存到磁盘的文件。我尝试将文件从 API url 直接保存到本地存储,它似乎很慢。存储大约 500 张图像大约需要 30-40 秒。我尝试使用 urllib.request.urlretrieve、Pillow 和 dload、BytesIO,但它们都有几乎相同的结果。

标签: pythondjangopostgresql

解决方案


推荐阅读