fix: make master view auto-detect continuum versioning for model class
This commit is contained in:
parent
f33448f64a
commit
910ddca96f
2 changed files with 52 additions and 21 deletions
|
|
@ -350,14 +350,6 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
"configuring" - i.e. it should have a :meth:`configure()` view.
|
"configuring" - i.e. it should have a :meth:`configure()` view.
|
||||||
Default value is ``False``.
|
Default value is ``False``.
|
||||||
|
|
||||||
.. attribute:: has_versions
|
|
||||||
|
|
||||||
Boolean indicating whether the master view should expose
|
|
||||||
version history for its data records - i.e. it should have a
|
|
||||||
:meth:`view_versions()` view. Default value is ``False``.
|
|
||||||
|
|
||||||
See also :meth:`should_expose_versions()`.
|
|
||||||
|
|
||||||
.. attribute:: version_grid_columns
|
.. attribute:: version_grid_columns
|
||||||
|
|
||||||
List of columns for the :meth:`view_versions()` view grid.
|
List of columns for the :meth:`view_versions()` view grid.
|
||||||
|
|
@ -451,9 +443,6 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
rows_paginate_on_backend = True
|
rows_paginate_on_backend = True
|
||||||
rows_viewable = False
|
rows_viewable = False
|
||||||
|
|
||||||
# versioning features
|
|
||||||
has_versions = False
|
|
||||||
|
|
||||||
# current action
|
# current action
|
||||||
listing = False
|
listing = False
|
||||||
creating = False
|
creating = False
|
||||||
|
|
@ -914,12 +903,40 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
# version history methods
|
# version history methods
|
||||||
##############################
|
##############################
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_versioned(cls):
|
||||||
|
"""
|
||||||
|
Returns boolean indicating whether the model class is
|
||||||
|
configured for SQLAlchemy-Continuum versioning.
|
||||||
|
|
||||||
|
The default logic will directly inspect the model class, as
|
||||||
|
returned by :meth:`get_model_class()`. Or you can override by
|
||||||
|
setting the ``model_is_versioned`` attribute::
|
||||||
|
|
||||||
|
class WidgetView(MasterView):
|
||||||
|
model_class = Widget
|
||||||
|
model_is_versioned = False
|
||||||
|
|
||||||
|
See also :meth:`should_expose_versions()`.
|
||||||
|
|
||||||
|
:returns: ``True`` if the model class is versioned; else
|
||||||
|
``False``.
|
||||||
|
"""
|
||||||
|
if hasattr(cls, "model_is_versioned"):
|
||||||
|
return cls.model_is_versioned
|
||||||
|
|
||||||
|
model_class = cls.get_model_class()
|
||||||
|
if hasattr(model_class, "__versioned__"):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_model_version_class(cls):
|
def get_model_version_class(cls):
|
||||||
"""
|
"""
|
||||||
Returns the version class for the master model class.
|
Returns the version class for the master model class.
|
||||||
|
|
||||||
Should only be relevant if :attr:`has_versions` is true.
|
Should only be relevant if :meth:`is_versioned()` is true.
|
||||||
"""
|
"""
|
||||||
import sqlalchemy_continuum as continuum # pylint: disable=import-outside-toplevel
|
import sqlalchemy_continuum as continuum # pylint: disable=import-outside-toplevel
|
||||||
|
|
||||||
|
|
@ -931,14 +948,14 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
be exposed for the current user. This will return ``True``
|
be exposed for the current user. This will return ``True``
|
||||||
unless any of the following are ``False``:
|
unless any of the following are ``False``:
|
||||||
|
|
||||||
* :attr:`has_versions`
|
* :meth:`is_versioned()`
|
||||||
* :meth:`wuttjamaican:wuttjamaican.app.AppHandler.continuum_is_enabled()`
|
* :meth:`wuttjamaican:wuttjamaican.app.AppHandler.continuum_is_enabled()`
|
||||||
* ``self.has_perm("versions")`` - cf. :meth:`has_perm()`
|
* ``self.has_perm("versions")`` - cf. :meth:`has_perm()`
|
||||||
|
|
||||||
:returns: ``True`` if versioning should be exposed for current
|
:returns: ``True`` if versioning should be exposed for current
|
||||||
user; else ``False``.
|
user; else ``False``.
|
||||||
"""
|
"""
|
||||||
if not self.has_versions:
|
if not self.is_versioned():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not self.app.continuum_is_enabled():
|
if not self.app.continuum_is_enabled():
|
||||||
|
|
@ -958,8 +975,8 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
``/widgets/XXX/versions/`` where ``XXX`` represents the key/ID
|
``/widgets/XXX/versions/`` where ``XXX`` represents the key/ID
|
||||||
for the record.
|
for the record.
|
||||||
|
|
||||||
By default, this view is included only if :attr:`has_versions`
|
By default, this view is included only if
|
||||||
is true.
|
:meth:`is_versioned()` is true.
|
||||||
|
|
||||||
The default view logic will show a "grid" (table) with the
|
The default view logic will show a "grid" (table) with the
|
||||||
record's version history.
|
record's version history.
|
||||||
|
|
@ -1147,8 +1164,8 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
key/ID for the record and YYY represents a
|
key/ID for the record and YYY represents a
|
||||||
SQLAlchemy-Continuum ``transaction.id``.
|
SQLAlchemy-Continuum ``transaction.id``.
|
||||||
|
|
||||||
By default, this view is included only if :attr:`has_versions`
|
By default, this view is included only if
|
||||||
is true.
|
:meth:`is_versioned()` is true.
|
||||||
|
|
||||||
The default view logic will display a "diff" table showing how
|
The default view logic will display a "diff" table showing how
|
||||||
the record's values were changed within a transaction.
|
the record's values were changed within a transaction.
|
||||||
|
|
@ -3618,7 +3635,7 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
||||||
)
|
)
|
||||||
|
|
||||||
# version history
|
# version history
|
||||||
if cls.has_versions and app.continuum_is_enabled():
|
if cls.is_versioned() and app.continuum_is_enabled():
|
||||||
instance_url_prefix = cls.get_instance_url_prefix()
|
instance_url_prefix = cls.get_instance_url_prefix()
|
||||||
config.add_wutta_permission(
|
config.add_wutta_permission(
|
||||||
permission_prefix,
|
permission_prefix,
|
||||||
|
|
|
||||||
|
|
@ -1849,10 +1849,24 @@ class TestVersionedMasterView(VersionWebTestCase):
|
||||||
def make_view(self):
|
def make_view(self):
|
||||||
return mod.MasterView(self.request)
|
return mod.MasterView(self.request)
|
||||||
|
|
||||||
|
def test_is_versioned(self):
|
||||||
|
model = self.app.model
|
||||||
|
|
||||||
|
with patch.object(mod.MasterView, "model_class", new=model.User):
|
||||||
|
|
||||||
|
# User is versioned by default
|
||||||
|
self.assertTrue(mod.MasterView.is_versioned())
|
||||||
|
|
||||||
|
# but view can override w/ attr
|
||||||
|
with patch.object(
|
||||||
|
mod.MasterView, "model_is_versioned", new=False, create=True
|
||||||
|
):
|
||||||
|
self.assertFalse(mod.MasterView.is_versioned())
|
||||||
|
|
||||||
def test_defaults(self):
|
def test_defaults(self):
|
||||||
model = self.app.model
|
model = self.app.model
|
||||||
|
|
||||||
with patch.multiple(mod.MasterView, model_class=model.User, has_versions=True):
|
with patch.object(mod.MasterView, "model_class", new=model.User):
|
||||||
mod.MasterView.defaults(self.pyramid_config)
|
mod.MasterView.defaults(self.pyramid_config)
|
||||||
|
|
||||||
def test_get_model_version_class(self):
|
def test_get_model_version_class(self):
|
||||||
|
|
@ -1864,7 +1878,7 @@ class TestVersionedMasterView(VersionWebTestCase):
|
||||||
|
|
||||||
def test_should_expose_versions(self):
|
def test_should_expose_versions(self):
|
||||||
model = self.app.model
|
model = self.app.model
|
||||||
with patch.multiple(mod.MasterView, model_class=model.User, has_versions=True):
|
with patch.object(mod.MasterView, "model_class", new=model.User):
|
||||||
|
|
||||||
# fully enabled for root user
|
# fully enabled for root user
|
||||||
with patch.object(self.request, "is_root", new=True):
|
with patch.object(self.request, "is_root", new=True):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue