Add timestamp field on ModelStorage for last modified

Closes #14202
This commit is contained in:
Cédric Krier
2026-02-25 09:04:03 +01:00
parent 62bc81360b
commit 071d5e4fef
10 changed files with 21 additions and 11 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ class ImageURLMixin:
args['h'] = height
if index is not None:
args['i'] = index
timestamp = int((self.write_date or self.create_date).timestamp())
timestamp = int(self.last_modified_at.timestamp())
args['t'] = (
base64.urlsafe_b64encode(timestamp.to_bytes(8, 'big'))
.decode().rstrip('='))
+1 -1
View File
@@ -116,7 +116,7 @@ class ProductImageTestCase(ModuleTestCase):
).read()
image.save()
template.write_date = dt.datetime(2025, 1, 1) # fix timestamp
template.last_modified_at = dt.datetime(2025, 1, 1) # fix timestamp
self.assertRegex(
template.get_image_url(i=2),
+1 -1
View File
@@ -406,7 +406,7 @@ class WorkCycle(Workflow, ModelSQL, ModelView):
def set_duration(self, now):
if self.duration is None:
self.duration = now - (self.write_date or self.create_date)
self.duration = now - self.last_modified_at
def set_cost(self):
if self.cost is None:
+1 -2
View File
@@ -442,8 +442,7 @@ class UserSession(ModelSQL):
@property
def expired(self):
now = datetime.datetime.now()
timestamp = self.write_date or self.create_date
return abs(timestamp - now) > self.timeout()
return abs(self.last_modified_at - now) > self.timeout()
@classmethod
def reset(cls, session):
+1
View File
@@ -1,3 +1,4 @@
* Add timestamp field on ModelSQL for last modified
* Support Function field without getter but SQL expression
* Add support for column_<field name> method
* Use tables and Model as arguments for sql_column of the Field
+3
View File
@@ -65,6 +65,9 @@ this repository contains the full copyright notices and license terms. -->
<record model="ir.message" id="msg_edited_at">
<field name="text">Edited at</field>
</record>
<record model="ir.message" id="msg_last_modified_at">
<field name="text">Last Modified at</field>
</record>
<record model="ir.message" id="msg_record_name">
<field name="text">Record Name</field>
</record>
+1 -1
View File
@@ -17,7 +17,7 @@ from trytond.wsgi import app
def get_token(record):
return str((record.write_date or record.create_date).timestamp())
return str(record.last_modified_at.timestamp())
def get_config(names, section='html', default=None):
+2 -2
View File
@@ -96,7 +96,7 @@ class Session(ModelSQL):
if abs(session.create_date - now) < timeout:
if compare_digest(session.key, key):
find = True
last_reset = session.write_date or session.create_date
last_reset = session.last_modified_at
else:
if find is None and compare_digest(session.key, key):
find = False
@@ -120,7 +120,7 @@ class Session(ModelSQL):
('key', '=', key),
domain or [],
], limit=1)
timestamp = session.write_date or session.create_date
timestamp = session.last_modified_at
valid = abs(timestamp - now) < timeout
if not valid:
cls.delete([session])
+9 -1
View File
@@ -16,7 +16,7 @@ from sql.operators import And, Concat, Equal, Exists, Operator, Or
from trytond import backend, config
from trytond.cache import freeze
from trytond.exceptions import ConcurrencyException
from trytond.i18n import gettext
from trytond.i18n import gettext, lazy_gettext
from trytond.pool import Pool
from trytond.pyson import PYSONDecoder, PYSONEncoder
from trytond.rpc import RPC
@@ -322,6 +322,9 @@ class ModelSQL(ModelStorage):
_history = False
table_query = None
last_modified_at = fields.Function(fields.Timestamp(
lazy_gettext('ir.msg_last_modified_at')))
@classmethod
def __setup__(cls):
cls._table = config.get('table', cls.__name__, default=cls._table)
@@ -956,6 +959,11 @@ class ModelSQL(ModelStorage):
raise ConcurrencyException(
'Records were modified in the meanwhile')
@classmethod
def column_last_modified_at(cls, tables):
table, _ = tables[None]
return Coalesce(table.write_date, table.create_date)
@classmethod
@no_table_query
def create(cls, vlist):
+1 -2
View File
@@ -325,8 +325,7 @@ class User(avatar_mixin(100, 'login'), DeactivableMixin, ModelSQL, ModelView):
], order=[('create_uid', 'ASC')])
def filter_(session):
timestamp = session.write_date or session.create_date
return abs(timestamp - now) < timeout
return abs(session.last_modified_at - now) < timeout
result.update(dict((i, len(list(g)))
for i, g in groupby(filter(filter_, sessions),
attrgetter('create_uid.id'))))