mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-01 03:00:54 +00:00
Refctor image downloader (#3393)
* Adds configurable setting for maximum remote image size * Add helper function for downloading image from remote URL - Will replace existing function - Performs more thorough sanity checking * Replace existing image downloading code - part image uses new generic function - company image uses new generic function * Rearrange settings * Refactor and cleanup existing views / forms * Add unit testing for image downloader function * Refactor image downloader forms - Part image download now uses the API - Company image download now uses the API - Remove outdated forms / views / templates * Increment API version * Prevent remote image download via API if the setting is not enabled * Do not attempt to validate or extract image from blank URL * Fix custom save() serializer methods
This commit is contained in:
@ -1,8 +1,10 @@
|
||||
"""DRF data serializers for Part app."""
|
||||
|
||||
import imghdr
|
||||
import io
|
||||
from decimal import Decimal
|
||||
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db import models, transaction
|
||||
from django.db.models import ExpressionWrapper, F, FloatField, Q
|
||||
from django.db.models.functions import Coalesce
|
||||
@ -22,7 +24,7 @@ from InvenTree.serializers import (DataFileExtractSerializer,
|
||||
InvenTreeDecimalField,
|
||||
InvenTreeImageSerializerField,
|
||||
InvenTreeModelSerializer,
|
||||
InvenTreeMoneySerializer)
|
||||
InvenTreeMoneySerializer, RemoteImageMixin)
|
||||
from InvenTree.status_codes import BuildStatus
|
||||
|
||||
from .models import (BomItem, BomItemSubstitute, Part, PartAttachment,
|
||||
@ -273,7 +275,7 @@ class PartBriefSerializer(InvenTreeModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class PartSerializer(InvenTreeModelSerializer):
|
||||
class PartSerializer(RemoteImageMixin, InvenTreeModelSerializer):
|
||||
"""Serializer for complete detail information of a part.
|
||||
|
||||
Used when displaying all details of a single component.
|
||||
@ -424,6 +426,7 @@ class PartSerializer(InvenTreeModelSerializer):
|
||||
'parameters',
|
||||
'pk',
|
||||
'purchaseable',
|
||||
'remote_image',
|
||||
'revision',
|
||||
'salable',
|
||||
'starred',
|
||||
@ -437,6 +440,31 @@ class PartSerializer(InvenTreeModelSerializer):
|
||||
'virtual',
|
||||
]
|
||||
|
||||
def save(self):
|
||||
"""Save the Part instance"""
|
||||
|
||||
super().save()
|
||||
|
||||
part = self.instance
|
||||
|
||||
# Check if an image was downloaded from a remote URL
|
||||
remote_img = getattr(self, 'remote_image_file', None)
|
||||
|
||||
if remote_img and part:
|
||||
fmt = remote_img.format or 'PNG'
|
||||
buffer = io.BytesIO()
|
||||
remote_img.save(buffer, format=fmt)
|
||||
|
||||
# Construct a simplified name for the image
|
||||
filename = f"part_{part.pk}_image.{fmt.lower()}"
|
||||
|
||||
part.image.save(
|
||||
filename,
|
||||
ContentFile(buffer.getvalue()),
|
||||
)
|
||||
|
||||
return self.instance
|
||||
|
||||
|
||||
class PartRelationSerializer(InvenTreeModelSerializer):
|
||||
"""Serializer for a PartRelated model."""
|
||||
|
Reference in New Issue
Block a user