Compare commits
3 commits
38e5d9eb38
...
dcdc0e7dab
Author | SHA1 | Date | |
---|---|---|---|
![]() |
dcdc0e7dab | ||
![]() |
ba9021c990 | ||
![]() |
6085ea78ec |
|
@ -1940,6 +1940,15 @@ class Grid:
|
||||||
})
|
})
|
||||||
return filters
|
return filters
|
||||||
|
|
||||||
|
def object_to_dict(self, obj):
|
||||||
|
""" """
|
||||||
|
try:
|
||||||
|
dct = dict(obj)
|
||||||
|
except TypeError:
|
||||||
|
dct = dict(obj.__dict__)
|
||||||
|
dct.pop('_sa_instance_state', None)
|
||||||
|
return dct
|
||||||
|
|
||||||
def get_vue_context(self):
|
def get_vue_context(self):
|
||||||
"""
|
"""
|
||||||
Returns a dict of context for the grid, for use with the Vue
|
Returns a dict of context for the grid, for use with the Vue
|
||||||
|
@ -1976,7 +1985,7 @@ class Grid:
|
||||||
original_record = record
|
original_record = record
|
||||||
|
|
||||||
# convert record to new dict
|
# convert record to new dict
|
||||||
record = dict(record)
|
record = self.object_to_dict(record)
|
||||||
|
|
||||||
# make all values safe for json
|
# make all values safe for json
|
||||||
record = make_json_safe(record, warn=False)
|
record = make_json_safe(record, warn=False)
|
||||||
|
|
|
@ -682,13 +682,13 @@
|
||||||
<%def name="render_crud_header_buttons()">
|
<%def name="render_crud_header_buttons()">
|
||||||
% if master:
|
% if master:
|
||||||
% if master.viewing:
|
% if master.viewing:
|
||||||
% if instance_editable and master.has_perm('edit'):
|
% if master.editable and instance_editable and master.has_perm('edit'):
|
||||||
<wutta-button once
|
<wutta-button once
|
||||||
tag="a" href="${master.get_action_url('edit', instance)}"
|
tag="a" href="${master.get_action_url('edit', instance)}"
|
||||||
icon-left="edit"
|
icon-left="edit"
|
||||||
label="Edit This" />
|
label="Edit This" />
|
||||||
% endif
|
% endif
|
||||||
% if instance_deletable and master.has_perm('delete'):
|
% if master.deletable and instance_deletable and master.has_perm('delete'):
|
||||||
<wutta-button once type="is-danger"
|
<wutta-button once type="is-danger"
|
||||||
tag="a" href="${master.get_action_url('delete', instance)}"
|
tag="a" href="${master.get_action_url('delete', instance)}"
|
||||||
icon-left="trash"
|
icon-left="trash"
|
||||||
|
@ -701,7 +701,7 @@
|
||||||
icon-left="eye"
|
icon-left="eye"
|
||||||
label="View This" />
|
label="View This" />
|
||||||
% endif
|
% endif
|
||||||
% if instance_deletable and master.has_perm('delete'):
|
% if master.deletable and instance_deletable and master.has_perm('delete'):
|
||||||
<wutta-button once type="is-danger"
|
<wutta-button once type="is-danger"
|
||||||
tag="a" href="${master.get_action_url('delete', instance)}"
|
tag="a" href="${master.get_action_url('delete', instance)}"
|
||||||
icon-left="trash"
|
icon-left="trash"
|
||||||
|
@ -714,7 +714,7 @@
|
||||||
icon-left="eye"
|
icon-left="eye"
|
||||||
label="View This" />
|
label="View This" />
|
||||||
% endif
|
% endif
|
||||||
% if instance_editable and master.has_perm('edit'):
|
% if master.editable and instance_editable and master.has_perm('edit'):
|
||||||
<wutta-button once
|
<wutta-button once
|
||||||
tag="a" href="${master.get_action_url('edit', instance)}"
|
tag="a" href="${master.get_action_url('edit', instance)}"
|
||||||
icon-left="edit"
|
icon-left="edit"
|
||||||
|
|
|
@ -1629,6 +1629,9 @@ class MasterView(View):
|
||||||
if 'instance_deletable' not in context:
|
if 'instance_deletable' not in context:
|
||||||
context['instance_deletable'] = self.is_deletable(instance)
|
context['instance_deletable'] = self.is_deletable(instance)
|
||||||
|
|
||||||
|
# supplement context further if needed
|
||||||
|
context = self.get_template_context(context)
|
||||||
|
|
||||||
# first try the template path most specific to this view
|
# first try the template path most specific to this view
|
||||||
template_prefix = self.get_template_prefix()
|
template_prefix = self.get_template_prefix()
|
||||||
mako_path = f'{template_prefix}/{template}.mako'
|
mako_path = f'{template_prefix}/{template}.mako'
|
||||||
|
@ -1648,6 +1651,26 @@ class MasterView(View):
|
||||||
# let that error raise on up
|
# let that error raise on up
|
||||||
return render_to_response(mako_path, context, request=self.request)
|
return render_to_response(mako_path, context, request=self.request)
|
||||||
|
|
||||||
|
def get_template_context(self, context):
|
||||||
|
"""
|
||||||
|
This method should return the "complete" context for rendering
|
||||||
|
the current view template.
|
||||||
|
|
||||||
|
Default logic for this method returns the given context
|
||||||
|
unchanged.
|
||||||
|
|
||||||
|
You may wish to override to pass extra context to the view
|
||||||
|
template. Check :attr:`viewing` and similar, or
|
||||||
|
``request.current_route_name`` etc. in order to add extra
|
||||||
|
context only for certain view templates.
|
||||||
|
|
||||||
|
:params: context: The context dict we have so far,
|
||||||
|
auto-provided by the master view logic.
|
||||||
|
|
||||||
|
:returns: Final context dict for the template.
|
||||||
|
"""
|
||||||
|
return context
|
||||||
|
|
||||||
def get_fallback_templates(self, template):
|
def get_fallback_templates(self, template):
|
||||||
"""
|
"""
|
||||||
Returns a list of "fallback" template paths which may be
|
Returns a list of "fallback" template paths which may be
|
||||||
|
@ -1995,8 +2018,12 @@ class MasterView(View):
|
||||||
:param obj: Model instance object.
|
:param obj: Model instance object.
|
||||||
"""
|
"""
|
||||||
route_prefix = self.get_route_prefix()
|
route_prefix = self.get_route_prefix()
|
||||||
kw = dict([(key, obj[key])
|
try:
|
||||||
for key in self.get_model_key()])
|
kw = dict([(key, obj[key])
|
||||||
|
for key in self.get_model_key()])
|
||||||
|
except TypeError:
|
||||||
|
kw = dict([(key, getattr(obj, key))
|
||||||
|
for key in self.get_model_key()])
|
||||||
kw.update(kwargs)
|
kw.update(kwargs)
|
||||||
return self.request.route_url(f'{route_prefix}.{action}', **kw)
|
return self.request.route_url(f'{route_prefix}.{action}', **kw)
|
||||||
|
|
||||||
|
|
|
@ -1373,6 +1373,25 @@ class TestGrid(WebTestCase):
|
||||||
filters = grid.get_vue_filters()
|
filters = grid.get_vue_filters()
|
||||||
self.assertEqual(len(filters), 2)
|
self.assertEqual(len(filters), 2)
|
||||||
|
|
||||||
|
def test_object_to_dict(self):
|
||||||
|
grid = self.make_grid()
|
||||||
|
setting = {'name': 'foo', 'value': 'bar'}
|
||||||
|
|
||||||
|
# new dict but with same values
|
||||||
|
dct = grid.object_to_dict(setting)
|
||||||
|
self.assertIsInstance(dct, dict)
|
||||||
|
self.assertIsNot(dct, setting)
|
||||||
|
self.assertEqual(dct, setting)
|
||||||
|
|
||||||
|
# random object, not iterable
|
||||||
|
class MockSetting:
|
||||||
|
def __init__(self, **kw):
|
||||||
|
self.__dict__.update(kw)
|
||||||
|
mock = MockSetting(**setting)
|
||||||
|
dct = grid.object_to_dict(mock)
|
||||||
|
self.assertIsInstance(dct, dict)
|
||||||
|
self.assertEqual(dct, setting)
|
||||||
|
|
||||||
def test_get_vue_context(self):
|
def test_get_vue_context(self):
|
||||||
|
|
||||||
# empty if no columns defined
|
# empty if no columns defined
|
||||||
|
|
|
@ -734,6 +734,41 @@ class TestMasterView(WebTestCase):
|
||||||
self.request.matchdict = {'name': 'blarg'}
|
self.request.matchdict = {'name': 'blarg'}
|
||||||
self.assertRaises(HTTPNotFound, view.get_instance, session=self.session)
|
self.assertRaises(HTTPNotFound, view.get_instance, session=self.session)
|
||||||
|
|
||||||
|
def test_get_action_url_for_dict(self):
|
||||||
|
model = self.app.model
|
||||||
|
setting = {'name': 'foo', 'value': 'bar'}
|
||||||
|
with patch.multiple(mod.MasterView, create=True,
|
||||||
|
model_class=model.Setting):
|
||||||
|
mod.MasterView.defaults(self.pyramid_config)
|
||||||
|
view = self.make_view()
|
||||||
|
url = view.get_action_url_view(setting, 0)
|
||||||
|
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
||||||
|
|
||||||
|
def test_get_action_url_for_orm_object(self):
|
||||||
|
model = self.app.model
|
||||||
|
setting = model.Setting(name='foo', value='bar')
|
||||||
|
self.session.add(setting)
|
||||||
|
self.session.commit()
|
||||||
|
with patch.multiple(mod.MasterView, create=True,
|
||||||
|
model_class=model.Setting):
|
||||||
|
mod.MasterView.defaults(self.pyramid_config)
|
||||||
|
view = self.make_view()
|
||||||
|
url = view.get_action_url_view(setting, 0)
|
||||||
|
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
||||||
|
|
||||||
|
def test_get_action_url_for_adhoc_object(self):
|
||||||
|
model = self.app.model
|
||||||
|
class MockSetting:
|
||||||
|
def __init__(self, **kw):
|
||||||
|
self.__dict__.update(kw)
|
||||||
|
setting = MockSetting(name='foo', value='bar')
|
||||||
|
with patch.multiple(mod.MasterView, create=True,
|
||||||
|
model_class=model.Setting):
|
||||||
|
mod.MasterView.defaults(self.pyramid_config)
|
||||||
|
view = self.make_view()
|
||||||
|
url = view.get_action_url_view(setting, 0)
|
||||||
|
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
||||||
|
|
||||||
def test_get_action_url_view(self):
|
def test_get_action_url_view(self):
|
||||||
model = self.app.model
|
model = self.app.model
|
||||||
setting = model.Setting(name='foo', value='bar')
|
setting = model.Setting(name='foo', value='bar')
|
||||||
|
|
Loading…
Reference in a new issue