|
|
@@ -24,11 +24,13 @@ __all__ = (
|
|
|
|
|
|
PLACEHOLDER_HTML = '<span class="text-muted">—</span>'
|
|
|
|
|
|
+IMAGE_DECODING_CHOICES = ('auto', 'async', 'sync')
|
|
|
|
|
|
#
|
|
|
# Attributes
|
|
|
#
|
|
|
|
|
|
+
|
|
|
class ObjectAttribute:
|
|
|
"""
|
|
|
Base class for representing an attribute of an object.
|
|
|
@@ -193,9 +195,37 @@ class ColorAttr(ObjectAttribute):
|
|
|
class ImageAttr(ObjectAttribute):
|
|
|
"""
|
|
|
An attribute representing an image field on the model. Displays the uploaded image.
|
|
|
+
|
|
|
+ Parameters:
|
|
|
+ load_lazy (bool): If True, the image will be loaded lazily (default: True)
|
|
|
+ decoding (str): Image decoding option ('async', 'sync', 'auto', None)
|
|
|
"""
|
|
|
template_name = 'ui/attrs/image.html'
|
|
|
|
|
|
+ def __init__(self, *args, load_lazy=True, decoding=None, **kwargs):
|
|
|
+ super().__init__(*args, **kwargs)
|
|
|
+ self.load_lazy = load_lazy
|
|
|
+
|
|
|
+ if decoding is not None and decoding not in IMAGE_DECODING_CHOICES:
|
|
|
+ raise ValueError(
|
|
|
+ _('Invalid decoding option: {decoding}! Must be one of {image_decoding_choices}').format(
|
|
|
+ decoding=decoding, image_decoding_choices=', '.join(IMAGE_DECODING_CHOICES)
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
+ # Compute default decoding:
|
|
|
+ # - lazy images: async decoding (performance-friendly hint)
|
|
|
+ # - non-lazy images: omit decoding (browser default/auto)
|
|
|
+ if decoding is None and load_lazy:
|
|
|
+ decoding = 'async'
|
|
|
+ self.decoding = decoding
|
|
|
+
|
|
|
+ def get_context(self, obj, context):
|
|
|
+ return {
|
|
|
+ 'decoding': self.decoding,
|
|
|
+ 'load_lazy': self.load_lazy,
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
class RelatedObjectAttr(ObjectAttribute):
|
|
|
"""
|