diff --git a/engine/core/graphene/object_types.py b/engine/core/graphene/object_types.py index b3f33358..25dfad6b 100644 --- a/engine/core/graphene/object_types.py +++ b/engine/core/graphene/object_types.py @@ -234,7 +234,7 @@ class CategoryType(DjangoObjectType): # type: ignore [misc] return result def resolve_image(self: Category, info) -> str: - return info.context.build_absolute_uri(self.image.url) if self.image else "" + return self.image_url def resolve_markup_percent(self: Category, info) -> float: if info.context.user.has_perm("core.view_category"): @@ -465,8 +465,8 @@ class ProductImageType(DjangoObjectType): # type: ignore [misc] filter_fields = ["uuid"] description = _("product's images") - def resolve_image(self: ProductImage, info): - return info.context.build_absolute_uri(self.image.url) if self.image else "" + def resolve_image(self: ProductImage, _info): + return self.image_url class ProductType(DjangoObjectType): # type: ignore [misc] diff --git a/engine/core/models.py b/engine/core/models.py index 9d7fd551..b545a646 100644 --- a/engine/core/models.py +++ b/engine/core/models.py @@ -420,6 +420,13 @@ class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel): # return list(by_attr.values()) # type: ignore [arg-type] + @cached_property + def image_url(self) -> str: + with suppress(ValueError): + url = str(self.image.url) + url = url if "http" in url else f"https://api.{config.BASE_DOMAIN}{url}" + return "" + class Meta: verbose_name = _("category") verbose_name_plural = _("categories") @@ -843,6 +850,13 @@ class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel): # t def __str__(self) -> str: return self.alt + @cached_property + def image_url(self) -> str: + with suppress(ValueError): + url = str(self.image.url) + url = url if "http" in url else f"https://api.{config.BASE_DOMAIN}{url}" + return "" + class Meta: ordering = ("priority",) verbose_name = _("product image") diff --git a/engine/core/serializers/detail.py b/engine/core/serializers/detail.py index 6a905c53..81484f3c 100644 --- a/engine/core/serializers/detail.py +++ b/engine/core/serializers/detail.py @@ -75,10 +75,8 @@ class CategoryDetailSerializer(ModelSerializer): "modified", ] - def get_image(self, obj: Category) -> str | None: - with suppress(ValueError): - return obj.image.url - return None + def get_image(self, obj: Category) -> str: + return obj.image_url def get_filterable_attributes(self, obj: Category) -> list[FilterableAttribute]: return obj.filterable_attributes @@ -175,7 +173,7 @@ class ProductImageDetailSerializer(ModelSerializer): ] def get_image(self, obj: ProductImage) -> str: - return obj.image.url or "" + return obj.image_url class AttributeDetailSerializer(ModelSerializer): diff --git a/engine/core/serializers/simple.py b/engine/core/serializers/simple.py index 0f7509f2..0b71e7d8 100644 --- a/engine/core/serializers/simple.py +++ b/engine/core/serializers/simple.py @@ -54,10 +54,8 @@ class CategorySimpleSerializer(ModelSerializer): # type: ignore [type-arg] "children", ] - def get_image(self, obj: Category) -> str | None: - with suppress(ValueError): - return str(obj.image.url) - return None + def get_image(self, obj: Category) -> str: + return obj.image_url def get_children(self, obj: Category) -> dict[str, Any]: request = self.context.get("request")