forked from erp-dev/erp
fix: change backfill product image
This commit is contained in:
@@ -6,12 +6,12 @@ from basic_info.models import Product
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '为没有图片的 Product 通过外部 image API 回补图片(使用 name_b64=base64url(product.name))'
|
||||
help = '为 image 为空但 get_primary_image_url() 非空的 Product 通过外部 image API 回补图片'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--merchant-id', type=int, help='仅处理指定商户的产品')
|
||||
parser.add_argument('--product-id', type=int, help='仅处理指定产品')
|
||||
parser.add_argument('--limit', type=int, help='最多处理多少条产品')
|
||||
parser.add_argument('--limit', type=int, help='最多处理多少条符合条件的产品')
|
||||
parser.add_argument(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
@@ -41,50 +41,65 @@ class Command(BaseCommand):
|
||||
if limit is not None:
|
||||
if int(limit) <= 0:
|
||||
raise CommandError('--limit 必须大于 0')
|
||||
queryset = queryset[: int(limit)]
|
||||
|
||||
products = list(queryset)
|
||||
self.stdout.write(f'待处理产品数: {len(products)}')
|
||||
|
||||
if options.get('dry_run'):
|
||||
for product in products:
|
||||
self.stdout.write(
|
||||
f'[DRY-RUN] product_id={product.id} merchant_id={product.merchant_id} name={product.name}'
|
||||
)
|
||||
self.stdout.write(self.style.SUCCESS('dry-run 完成'))
|
||||
return
|
||||
limit = int(limit)
|
||||
|
||||
success_count = 0
|
||||
failed_count = 0
|
||||
skipped_count = 0
|
||||
skipped_no_primary_count = 0
|
||||
selected_count = 0
|
||||
scanned_count = 0
|
||||
dry_run = bool(options.get('dry_run'))
|
||||
|
||||
for product in products:
|
||||
for product in queryset.iterator(chunk_size=1000):
|
||||
scanned_count += 1
|
||||
if product.image:
|
||||
skipped_count += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
image_payload = _fetch_external_product_image(product.name)
|
||||
_upload_product_image(product, image_payload)
|
||||
except Exception as exc:
|
||||
failed_count += 1
|
||||
self.stderr.write(
|
||||
self.style.ERROR(
|
||||
f'补图失败: product_id={product.id} merchant_id={product.merchant_id} '
|
||||
f'name={product.name} error={exc}'
|
||||
)
|
||||
)
|
||||
if not product.get_primary_image_url():
|
||||
skipped_no_primary_count += 1
|
||||
continue
|
||||
|
||||
success_count += 1
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f'补图成功: product_id={product.id} merchant_id={product.merchant_id} name={product.name}'
|
||||
selected_count += 1
|
||||
if dry_run:
|
||||
self.stdout.write(
|
||||
f'[DRY-RUN] product_id={product.id} merchant_id={product.merchant_id} name={product.name}'
|
||||
)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
image_payload = _fetch_external_product_image(product.name)
|
||||
_upload_product_image(product, image_payload)
|
||||
except Exception as exc:
|
||||
failed_count += 1
|
||||
self.stderr.write(
|
||||
self.style.ERROR(
|
||||
f'补图失败: product_id={product.id} merchant_id={product.merchant_id} '
|
||||
f'name={product.name} error={exc}'
|
||||
)
|
||||
)
|
||||
else:
|
||||
success_count += 1
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f'补图成功: product_id={product.id} merchant_id={product.merchant_id} name={product.name}'
|
||||
)
|
||||
)
|
||||
|
||||
if limit is not None and selected_count >= limit:
|
||||
break
|
||||
|
||||
if dry_run:
|
||||
self.stdout.write(self.style.SUCCESS('dry-run 完成'))
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f'完成: total={len(products)} success={success_count} failed={failed_count} skipped={skipped_count}'
|
||||
'完成: '
|
||||
f'scanned={scanned_count} '
|
||||
f'selected={selected_count} '
|
||||
f'success={success_count} '
|
||||
f'failed={failed_count} '
|
||||
f'skipped_with_image={skipped_count} '
|
||||
f'skipped_without_primary_url={skipped_no_primary_count}'
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user