Add basic "DB picker" support, for views which allow multiple engines
i.e. whichever engine is "current" will determine where data comes from
This commit is contained in:
parent
0d7492f6be
commit
839f6affe2
|
@ -132,6 +132,21 @@
|
|||
% endif
|
||||
</div>
|
||||
|
||||
% if expose_db_picker is not Undefined and expose_db_picker:
|
||||
<div class="level-item">
|
||||
<p>DB:</p>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
${h.form(url('change_db_engine'))}
|
||||
${h.csrf_token(request)}
|
||||
${h.hidden('engine_type', value=master.engine_type_key)}
|
||||
<div class="select">
|
||||
${h.select('dbkey', db_picker_selected, db_picker_options, id='db-picker')}
|
||||
</div>
|
||||
${h.end_form()}
|
||||
</div>
|
||||
% endif
|
||||
|
||||
</div><!-- level-left -->
|
||||
<div class="level-right">
|
||||
|
||||
|
@ -303,6 +318,13 @@
|
|||
var session_timeout = ${request.get_session_timeout() or 'null'};
|
||||
var logout_url = '${request.route_url('logout')}';
|
||||
var noop_url = '${request.route_url('noop')}';
|
||||
% if expose_db_picker is not Undefined and expose_db_picker:
|
||||
$(function() {
|
||||
$('#db-picker').change(function() {
|
||||
$(this).parents('form:first').submit();
|
||||
});
|
||||
});
|
||||
% endif
|
||||
% if expose_theme_picker and request.has_perm('common.change_app_theme'):
|
||||
$(function() {
|
||||
$('#theme-picker').change(function() {
|
||||
|
|
|
@ -143,6 +143,20 @@ class CommonView(View):
|
|||
self.request.session.flash("App theme has been changed to: {}".format(theme))
|
||||
return self.redirect(self.request.get_referrer())
|
||||
|
||||
def change_db_engine(self):
|
||||
"""
|
||||
Simple view which can change user's "current" database engine, of a
|
||||
given type, then redirect back to referring page.
|
||||
"""
|
||||
engine_type = self.request.POST.get('engine_type')
|
||||
if engine_type:
|
||||
dbkey = self.request.POST.get('dbkey')
|
||||
if dbkey:
|
||||
self.request.session['tailbone.engines.{}.current'.format(engine_type)] = dbkey
|
||||
if self.rattail_config.getbool('tailbone', 'engines.flash_after_change', default=True):
|
||||
self.request.session.flash("Switched '{}' database to: {}".format(engine_type, dbkey))
|
||||
return self.redirect(self.request.get_referrer())
|
||||
|
||||
def feedback(self):
|
||||
"""
|
||||
Generic view to handle the user feedback form.
|
||||
|
@ -212,6 +226,12 @@ class CommonView(View):
|
|||
config.add_route('mobile.about', '/mobile/about')
|
||||
config.add_view(cls, attr='about', route_name='mobile.about', renderer='/mobile/about.mako')
|
||||
|
||||
# change db engine
|
||||
config.add_tailbone_permission('common', 'common.change_db_engine',
|
||||
"Change which Database Engine is active (for user)")
|
||||
config.add_route('change_db_engine', '/change-db-engine', request_method='POST')
|
||||
config.add_view(cls, attr='change_db_engine', route_name='change_db_engine')
|
||||
|
||||
# change theme
|
||||
config.add_tailbone_permission('common', 'common.change_app_theme',
|
||||
"Change global App Template Theme")
|
||||
|
|
|
@ -36,6 +36,7 @@ import sqlalchemy as sa
|
|||
from sqlalchemy import orm
|
||||
|
||||
import sqlalchemy_continuum as continuum
|
||||
from sqlalchemy_utils.functions import get_primary_keys
|
||||
|
||||
from rattail.db import model, Session as RattailSession
|
||||
from rattail.db.continuum import model_transaction_query
|
||||
|
@ -47,6 +48,7 @@ from rattail.csvutil import UnicodeDictWriter
|
|||
from rattail.files import temp_path
|
||||
from rattail.excel import ExcelWriter
|
||||
from rattail.gpc import GPC
|
||||
from rattail.util import OrderedDict
|
||||
|
||||
import colander
|
||||
import deform
|
||||
|
@ -124,6 +126,11 @@ class MasterView(View):
|
|||
has_image = False
|
||||
has_thumbnail = False
|
||||
|
||||
# can set this to true, and set type key as needed, and implement some
|
||||
# other things also, to get a DB picker in the header for all views
|
||||
supports_multiple_engines = False
|
||||
engine_type_key = 'rattail'
|
||||
|
||||
row_attrs = {}
|
||||
cell_attrs = {}
|
||||
|
||||
|
@ -2096,8 +2103,9 @@ class MasterView(View):
|
|||
"""
|
||||
if hasattr(cls, 'model_key'):
|
||||
return cls.model_key
|
||||
mapper = orm.class_mapper(cls.get_model_class())
|
||||
return ','.join([k.key for k in mapper.primary_key])
|
||||
|
||||
pkeys = get_primary_keys(cls.get_model_class())
|
||||
return ','.join(pkeys)
|
||||
|
||||
@classmethod
|
||||
def get_model_title(cls):
|
||||
|
@ -2323,12 +2331,50 @@ class MasterView(View):
|
|||
return ['/mobile/master/{}.mako'.format(template)]
|
||||
return ['/master/{}.mako'.format(template)]
|
||||
|
||||
def get_current_engine_dbkey(self):
|
||||
"""
|
||||
Returns the "current" engine's dbkey, for the current user.
|
||||
"""
|
||||
return self.request.session.get('tailbone.engines.{}.current'.format(self.engine_type_key),
|
||||
'default')
|
||||
|
||||
def template_kwargs(self, **kwargs):
|
||||
"""
|
||||
Supplement the template context, for all views.
|
||||
"""
|
||||
# whether or not to show the DB picker?
|
||||
kwargs['expose_db_picker'] = False
|
||||
if self.supports_multiple_engines:
|
||||
|
||||
# view declares support for multiple engines, but we only want to
|
||||
# show the picker if we have more than one engine configured
|
||||
engines = self.get_db_engines()
|
||||
if len(engines) > 1:
|
||||
|
||||
# user session determines "current" db engine *of this type*
|
||||
# (note that many master views may declare the same type, and
|
||||
# would therefore share the "current" engine)
|
||||
selected = self.get_current_engine_dbkey()
|
||||
kwargs['expose_db_picker'] = True
|
||||
kwargs['db_picker_options'] = [tags.Option(k) for k in engines]
|
||||
kwargs['db_picker_selected'] = selected
|
||||
|
||||
return kwargs
|
||||
|
||||
def get_db_engines(self):
|
||||
"""
|
||||
Must return a dict (or even better, OrderedDict) which contains all
|
||||
supported database engines for the master view. Used with the DB
|
||||
picker feature.
|
||||
"""
|
||||
engines = OrderedDict()
|
||||
if self.rattail_config.rattail_engine:
|
||||
engines['default'] = self.rattail_config.rattail_engine
|
||||
for dbkey in sorted(self.rattail_config.rattail_engines):
|
||||
if dbkey != 'default':
|
||||
engines[dbkey] = self.rattail_config.rattail_engines[dbkey]
|
||||
return engines
|
||||
|
||||
##############################
|
||||
# Grid Stuff
|
||||
##############################
|
||||
|
@ -2446,7 +2492,8 @@ class MasterView(View):
|
|||
except orm.exc.UnmappedInstanceError:
|
||||
return {self.model_key: row[self.model_key]}
|
||||
else:
|
||||
keys = [k.key for k in mapper.primary_key]
|
||||
pkeys = get_primary_keys(row)
|
||||
keys = list(pkeys)
|
||||
values = [getattr(row, k) for k in keys]
|
||||
return dict(zip(keys, values))
|
||||
|
||||
|
|
Loading…
Reference in a new issue