@@ -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('='))
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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'))))
|
||||
|
||||
Reference in New Issue
Block a user