From 8911c22e3538cdba6f083dbe441ee9fe8cceb6cb Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 12 Nov 2026 11:42:43 +0000 Subject: [PATCH] More efficient thumbnail field --- .../InvenTree/InvenTree/serializers.py | 20 +++++++++++++++++++ src/backend/InvenTree/company/serializers.py | 3 ++- src/backend/InvenTree/part/serializers.py | 4 ++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/backend/InvenTree/InvenTree/serializers.py b/src/backend/InvenTree/InvenTree/serializers.py index 20a94b36c2..cb3297c5fc 100644 --- a/src/backend/InvenTree/InvenTree/serializers.py +++ b/src/backend/InvenTree/InvenTree/serializers.py @@ -944,6 +944,26 @@ class InvenTreeAttachmentSerializerField(serializers.FileField): return default_storage.url(str(value)) +class InvenTreeThumbnailField(serializers.CharField): + """Read-only field which renders the thumbnail URL for a model instance. + + The instance must implement get_thumbnail_url() (e.g. InvenTreeImageMixin). + + Note: This is more efficient than CharField(source='get_thumbnail_url'), + as DRF inspects the signature of a callable source for every serialized row. + """ + + def __init__(self, **kwargs): + """Initialize the field as read-only, sourced from the instance itself.""" + kwargs['source'] = '*' + kwargs['read_only'] = True + super().__init__(**kwargs) + + def to_representation(self, value): + """Return the thumbnail URL for the provided instance.""" + return value.get_thumbnail_url() + + class InvenTreeImageSerializerField(serializers.ImageField): """Custom image serializer. diff --git a/src/backend/InvenTree/company/serializers.py b/src/backend/InvenTree/company/serializers.py index 35d7b99acd..89e3468e6c 100644 --- a/src/backend/InvenTree/company/serializers.py +++ b/src/backend/InvenTree/company/serializers.py @@ -23,6 +23,7 @@ from InvenTree.serializers import ( InvenTreeModelSerializer, InvenTreeMoneySerializer, InvenTreeTaggitSerializer, + InvenTreeThumbnailField, OptionalField, apply_duplicate_copy_options, ) @@ -58,7 +59,7 @@ class CompanyBriefSerializer(InvenTreeModelSerializer): image = InvenTreeImageSerializerField(read_only=True) - thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) + thumbnail = InvenTreeThumbnailField() @register_importer() diff --git a/src/backend/InvenTree/part/serializers.py b/src/backend/InvenTree/part/serializers.py index d13ea6a691..32551a2a47 100644 --- a/src/backend/InvenTree/part/serializers.py +++ b/src/backend/InvenTree/part/serializers.py @@ -323,7 +323,7 @@ class PartBriefSerializer( image = InvenTree.serializers.InvenTreeImageSerializerField( read_only=True, allow_null=True ) - thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) + thumbnail = InvenTree.serializers.InvenTreeThumbnailField() IPN = serializers.CharField( required=False, @@ -840,7 +840,7 @@ class PartSerializer( image = InvenTree.serializers.InvenTreeImageSerializerField( required=False, allow_null=True ) - thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) + thumbnail = InvenTree.serializers.InvenTreeThumbnailField() starred = serializers.SerializerMethodField() # PrimaryKeyRelated fields (Note: enforcing field type here results in much faster queries, somehow...)