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.
|
||||
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
|
||||
|
||||
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_viewable = False
|
||||
|
||||
# versioning features
|
||||
has_versions = False
|
||||
|
||||
# current action
|
||||
listing = False
|
||||
creating = False
|
||||
|
|
@ -914,12 +903,40 @@ class MasterView(View): # pylint: disable=too-many-public-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
|
||||
def get_model_version_class(cls):
|
||||
"""
|
||||
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
|
||||
|
||||
|
|
@ -931,14 +948,14 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
|||
be exposed for the current user. This will return ``True``
|
||||
unless any of the following are ``False``:
|
||||
|
||||
* :attr:`has_versions`
|
||||
* :meth:`is_versioned()`
|
||||
* :meth:`wuttjamaican:wuttjamaican.app.AppHandler.continuum_is_enabled()`
|
||||
* ``self.has_perm("versions")`` - cf. :meth:`has_perm()`
|
||||
|
||||
:returns: ``True`` if versioning should be exposed for current
|
||||
user; else ``False``.
|
||||
"""
|
||||
if not self.has_versions:
|
||||
if not self.is_versioned():
|
||||
return False
|
||||
|
||||
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
|
||||
for the record.
|
||||
|
||||
By default, this view is included only if :attr:`has_versions`
|
||||
is true.
|
||||
By default, this view is included only if
|
||||
:meth:`is_versioned()` is true.
|
||||
|
||||
The default view logic will show a "grid" (table) with the
|
||||
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
|
||||
SQLAlchemy-Continuum ``transaction.id``.
|
||||
|
||||
By default, this view is included only if :attr:`has_versions`
|
||||
is true.
|
||||
By default, this view is included only if
|
||||
:meth:`is_versioned()` is true.
|
||||
|
||||
The default view logic will display a "diff" table showing how
|
||||
the record's values were changed within a transaction.
|
||||
|
|
@ -3618,7 +3635,7 @@ class MasterView(View): # pylint: disable=too-many-public-methods
|
|||
)
|
||||
|
||||
# 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()
|
||||
config.add_wutta_permission(
|
||||
permission_prefix,
|
||||
|
|
|
|||
|
|
@ -1849,10 +1849,24 @@ class TestVersionedMasterView(VersionWebTestCase):
|
|||
def make_view(self):
|
||||
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):
|
||||
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)
|
||||
|
||||
def test_get_model_version_class(self):
|
||||
|
|
@ -1864,7 +1878,7 @@ class TestVersionedMasterView(VersionWebTestCase):
|
|||
|
||||
def test_should_expose_versions(self):
|
||||
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
|
||||
with patch.object(self.request, "is_root", new=True):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue