Generalize ImageMixin to be used with other models than products

This commit is contained in:
Cédric Krier
2024-02-27 17:52:34 +01:00
parent ed718e31a3
commit 6bb7b6cc43
2 changed files with 53 additions and 42 deletions
+2 -2
View File
@@ -3,8 +3,8 @@
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.message" id="msg_product_image_size_unique">
<field name="text">The size of a product image must be unique.</field>
<record model="ir.message" id="msg_image_cache_size_unique">
<field name="text">The size of cached image must be unique.</field>
</record>
</data>
</tryton>
+51 -40
View File
@@ -9,7 +9,7 @@ import PIL.Image
from trytond.config import config
from trytond.model import (
MatchMixin, ModelSQL, ModelView, Unique, fields, sequence_ordered)
from trytond.pool import Pool, PoolMeta
from trytond.pool import PoolMeta
from trytond.pyson import Bool, Eval, If
from trytond.tools import slugify
from trytond.transaction import Transaction
@@ -72,8 +72,7 @@ class ImageURLMixin:
yield from self.images
def get_images(self, pattern):
pool = Pool()
Image = pool.get('product.image')
Image = self.__class__.images.get_target()
pattern = pattern.copy()
for key in set(pattern.keys()) - Image.allowed_match_keys():
del pattern[key]
@@ -106,38 +105,16 @@ class Product(ImageURLMixin, metaclass=PoolMeta):
yield image
class ImageMixin:
class _ImageMixin:
__slots__ = ()
image = fields.Binary(
"Image", file_id=file_id, store_prefix=store_prefix, required=True)
image_id = fields.Char("Image ID", readonly=True)
class Image(ImageMixin, sequence_ordered(), ModelSQL, ModelView, MatchMixin):
"Product Image"
__name__ = 'product.image'
template = fields.Many2One(
'product.template', "Product",
required=True, ondelete='CASCADE',
domain=[
If(Bool(Eval('product')),
('products', '=', Eval('product')),
()),
])
product = fields.Many2One(
'product.product', "Variant",
domain=[
If(Bool(Eval('template')),
('template', '=', Eval('template')),
()),
])
cache = fields.One2Many(
'product.image.cache', 'product_image', "Cache", readonly=True)
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.update(['product', 'template'])
class ImageMixin(_ImageMixin):
__slots__ = ()
cache = None
@classmethod
def allowed_match_keys(cls):
@@ -207,31 +184,58 @@ class Image(ImageMixin, sequence_ordered(), ModelSQL, ModelView, MatchMixin):
return data.getvalue()
def _store_cache(self, size, image):
pool = Pool()
Cache = pool.get('product.image.cache')
Cache = self.__class__.cache.get_target()
if isinstance(size, int):
width = height = size
else:
width, height = size
return Cache(
product_image=self,
image=image,
width=width,
height=height)
@classmethod
def clear_cache(cls, images):
pool = Pool()
Cache = pool.get('product.image.cache')
Cache = cls.cache.get_target()
caches = [c for i in images for c in i.cache]
Cache.delete(caches)
class ImageCache(ImageMixin, ModelSQL):
"Product Image Cache"
__name__ = 'product.image.cache'
product_image = fields.Many2One(
'product.image', "Product Image", required=True, ondelete='CASCADE')
class Image(ImageMixin, sequence_ordered(), ModelSQL, ModelView, MatchMixin):
"Product Image"
__name__ = 'product.image'
template = fields.Many2One(
'product.template', "Product",
required=True, ondelete='CASCADE',
domain=[
If(Bool(Eval('product')),
('products', '=', Eval('product')),
()),
])
product = fields.Many2One(
'product.product', "Variant",
domain=[
If(Bool(Eval('template')),
('template', '=', Eval('template')),
()),
])
cache = fields.One2Many(
'product.image.cache', 'product_image', "Cache", readonly=True)
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.update(['product', 'template'])
def _store_cache(self, size, image):
cache = super()._store_cache(size, image)
cache.product_image = self
return cache
class ImageCacheMixin(_ImageMixin):
__slots__ = ()
width = fields.Integer(
"Width", required=True,
domain=[
@@ -245,13 +249,20 @@ class ImageCache(ImageMixin, ModelSQL):
('height', '<=', SIZE_MAX),
])
class ImageCache(ImageCacheMixin, ModelSQL):
"Product Image Cache"
__name__ = 'product.image.cache'
product_image = fields.Many2One(
'product.image', "Product Image", required=True, ondelete='CASCADE')
@classmethod
def __setup__(cls):
super().__setup__()
t = cls.__table__()
cls._sql_constraints += [
('dimension_unique', Unique(t, t.product_image, t.width, t.height),
'ir.msg_product_image_size_unique'),
'product_image.msg_image_cache_size_unique'),
]
@classmethod