diff --git a/docs/api/wuttaweb/grids.base.rst b/docs/api/wuttaweb/grids.base.rst deleted file mode 100644 index 8b3cc38..0000000 --- a/docs/api/wuttaweb/grids.base.rst +++ /dev/null @@ -1,6 +0,0 @@ - -``wuttaweb.grids.base`` -======================= - -.. automodule:: wuttaweb.grids.base - :members: diff --git a/docs/api/wuttaweb/grids.rst b/docs/api/wuttaweb/grids.rst deleted file mode 100644 index 7430a21..0000000 --- a/docs/api/wuttaweb/grids.rst +++ /dev/null @@ -1,6 +0,0 @@ - -``wuttaweb.grids`` -================== - -.. automodule:: wuttaweb.grids - :members: diff --git a/docs/api/wuttaweb/index.rst b/docs/api/wuttaweb/index.rst index 1b1a61f..5afd18b 100644 --- a/docs/api/wuttaweb/index.rst +++ b/docs/api/wuttaweb/index.rst @@ -12,8 +12,6 @@ db forms forms.base - grids - grids.base handler helpers menus diff --git a/src/wuttaweb/forms/__init__.py b/src/wuttaweb/forms/__init__.py index 0f72808..35102be 100644 --- a/src/wuttaweb/forms/__init__.py +++ b/src/wuttaweb/forms/__init__.py @@ -26,7 +26,6 @@ Forms Library The ``wuttaweb.forms`` namespace contains the following: * :class:`~wuttaweb.forms.base.Form` -* :class:`~wuttaweb.forms.base.FieldList` """ -from .base import Form, FieldList +from .base import Form diff --git a/src/wuttaweb/forms/base.py b/src/wuttaweb/forms/base.py index 89664e3..42abb31 100644 --- a/src/wuttaweb/forms/base.py +++ b/src/wuttaweb/forms/base.py @@ -44,8 +44,7 @@ class FieldList(list): of :class:`python:list`. You normally would not need to instantiate this yourself, but it - is used under the hood for :attr:`Form.fields` as well as - :attr:`~wuttaweb.grids.base.Grid.columns`. + is used under the hood for e.g. :attr:`Form.fields`. """ def insert_before(self, field, newfield): @@ -106,48 +105,15 @@ class Form: Form instances contain the following attributes: - .. attribute:: request - - Reference to current :term:`request` object. - .. attribute:: fields :class:`FieldList` instance containing string field names for the form. By default, fields will appear in the same order as they are in this list. - .. attribute:: schema + .. attribute:: request - Colander-based schema object for the form. This is optional; - if not specified an attempt will be made to construct one - automatically. - - See also :meth:`get_schema()`. - - .. attribute:: model_class - - Optional "class" for the model. If set, this usually would be - a SQLAlchemy mapped class. This may be used instead of - specifying the :attr:`schema`. - - .. attribute:: model_instance - - Optional instance from which initial form data should be - obtained. In simple cases this might be a dict, or maybe an - instance of :attr:`model_class`. - - Note that this also may be used instead of specifying the - :attr:`schema`, if the instance belongs to a class which is - SQLAlchemy-mapped. (In that case :attr:`model_class` can be - determined automatically.) - - .. attribute:: readonly - - Boolean indicating the form does not allow submit. In practice - this means there will not even be a ``
`` tag involved. - - Default for this is ``False`` in which case the ```` tag - will exist and submit is allowed. + Reference to current :term:`request` object. .. attribute:: action_url @@ -194,9 +160,6 @@ class Form: request, fields=None, schema=None, - model_class=None, - model_instance=None, - readonly=False, labels={}, action_url=None, vue_tagname='wutta-form', @@ -208,7 +171,6 @@ class Form: ): self.request = request self.schema = schema - self.readonly = readonly self.labels = labels or {} self.action_url = action_url self.vue_tagname = vue_tagname @@ -221,9 +183,6 @@ class Form: self.config = self.request.wutta_config self.app = self.config.get_app() - self.model_class = model_class - self.model_instance = model_instance - if fields is not None: self.set_fields(fields) elif self.schema: @@ -300,22 +259,9 @@ class Form: """ Return the :class:`colander:colander.Schema` object for the form, generating it automatically if necessary. - - Note that if :attr:`schema` is already set, that will be - returned as-is. """ if not self.schema: - - if self.fields: - schema = colander.Schema() - for name in self.fields: - schema.add(colander.SchemaNode( - colander.String(), - name=name)) - self.schema = schema - - else: # no fields - raise NotImplementedError + raise NotImplementedError return self.schema @@ -326,12 +272,7 @@ class Form: """ if not hasattr(self, 'deform_form'): schema = self.get_schema() - kwargs = {} - - if self.model_instance: - kwargs['appstruct'] = self.model_instance - - form = deform.Form(schema, **kwargs) + form = deform.Form(schema) self.deform_form = form return self.deform_form @@ -391,7 +332,7 @@ class Form: output = render(template, context) return HTML.literal(output) - def render_vue_field(self, fieldname, readonly=None): + def render_vue_field(self, fieldname): """ Render the given field completely, i.e. ```` wrapper with label and containing a widget. @@ -408,19 +349,11 @@ class Form: """ - - if readonly is None: - readonly = self.readonly - - # render the field widget or whatever dform = self.get_deform() field = dform[fieldname] - kw = {} - if readonly: - kw['readonly'] = True - html = field.serialize(**kw) - # mark all that as safe + # render the field widget or whatever + html = field.serialize() html = HTML.literal(html) # render field label diff --git a/src/wuttaweb/grids/__init__.py b/src/wuttaweb/grids/__init__.py deleted file mode 100644 index a28f02c..0000000 --- a/src/wuttaweb/grids/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8; -*- -################################################################################ -# -# wuttaweb -- Web App for Wutta Framework -# Copyright © 2024 Lance Edgar -# -# This file is part of Wutta Framework. -# -# Wutta Framework is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# Wutta Framework is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# Wutta Framework. If not, see . -# -################################################################################ -""" -Grids Library - -The ``wuttaweb.grids`` namespace contains the following: - -* :class:`~wuttaweb.grids.base.Grid` -""" - -from .base import Grid, GridAction diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py deleted file mode 100644 index 17eaa3f..0000000 --- a/src/wuttaweb/grids/base.py +++ /dev/null @@ -1,344 +0,0 @@ -# -*- coding: utf-8; -*- -################################################################################ -# -# wuttaweb -- Web App for Wutta Framework -# Copyright © 2024 Lance Edgar -# -# This file is part of Wutta Framework. -# -# Wutta Framework is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# Wutta Framework is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# Wutta Framework. If not, see . -# -################################################################################ -""" -Base grid classes -""" - -from pyramid.renderers import render -from webhelpers2.html import HTML - -from wuttaweb.forms import FieldList - - -class Grid: - """ - Base class for all grids. - - :param request: Reference to current :term:`request` object. - - :param columns: List of column names for the grid. This is - optional; if not specified an attempt will be made to deduce - the list automatically. See also :attr:`columns`. - - .. note:: - - Some parameters are not explicitly described above. However - their corresponding attributes are described below. - - Grid instances contain the following attributes: - - .. attribute:: key - - Presumably unique key for the grid; used to track per-grid - sort/filter settings etc. - - .. attribute:: columns - - :class:`~wuttaweb.forms.base.FieldList` instance containing - string column names for the grid. Columns will appear in the - same order as they are in this list. - - See also :meth:`set_columns()`. - - .. attribute:: data - - Data set for the grid. This should either be a list of dicts - (or objects with dict-like access to fields, corresponding to - model records) or else an object capable of producing such a - list, e.g. SQLAlchemy query. - - .. attribute:: actions - - List of :class:`GridAction` instances represenging action links - to be shown for each record in the grid. - - .. attribute:: vue_tagname - - String name for Vue component tag. By default this is - ``'wutta-grid'``. See also :meth:`render_vue_tag()`. - """ - - def __init__( - self, - request, - key=None, - columns=None, - data=None, - actions=[], - vue_tagname='wutta-grid', - ): - self.request = request - self.key = key - self.data = data - self.actions = actions or [] - self.vue_tagname = vue_tagname - - self.config = self.request.wutta_config - self.app = self.config.get_app() - - if columns is not None: - self.set_columns(columns) - else: - self.columns = None - - @property - def vue_component(self): - """ - String name for the Vue component, e.g. ``'WuttaGrid'``. - - This is a generated value based on :attr:`vue_tagname`. - """ - words = self.vue_tagname.split('-') - return ''.join([word.capitalize() for word in words]) - - def set_columns(self, columns): - """ - Explicitly set the list of grid columns. - - This will overwrite :attr:`columns` with a new - :class:`~wuttaweb.forms.base.FieldList` instance. - - :param columns: List of string column names. - """ - self.columns = FieldList(columns) - - def render_vue_tag(self, **kwargs): - """ - Render the Vue component tag for the grid. - - By default this simply returns: - - .. code-block:: html - - - - The actual output will depend on various grid attributes, in - particular :attr:`vue_tagname`. - """ - return HTML.tag(self.vue_tagname, **kwargs) - - def render_vue_template( - self, - template='/grids/vue_template.mako', - **context): - """ - Render the Vue template block for the grid. - - This returns something like: - - .. code-block:: none - - - - .. todo:: - - Why can't Sphinx render the above code block as 'html' ? - - It acts like it can't handle a `` diff --git a/src/wuttaweb/templates/grids/vue_template.mako b/src/wuttaweb/templates/grids/vue_template.mako deleted file mode 100644 index 8429ef5..0000000 --- a/src/wuttaweb/templates/grids/vue_template.mako +++ /dev/null @@ -1,48 +0,0 @@ -## -*- coding: utf-8; -*- - - - - diff --git a/src/wuttaweb/templates/master/form.mako b/src/wuttaweb/templates/master/form.mako deleted file mode 100644 index 72edaa2..0000000 --- a/src/wuttaweb/templates/master/form.mako +++ /dev/null @@ -1,5 +0,0 @@ -## -*- coding: utf-8; -*- -<%inherit file="/form.mako" /> - - -${parent.body()} diff --git a/src/wuttaweb/templates/master/index.mako b/src/wuttaweb/templates/master/index.mako index 2b6f14b..fd3d573 100644 --- a/src/wuttaweb/templates/master/index.mako +++ b/src/wuttaweb/templates/master/index.mako @@ -3,30 +3,11 @@ <%def name="title()">${index_title} -## nb. avoid hero bar for index page <%def name="content_title()"> <%def name="page_content()"> - % if grid is not Undefined: - ${grid.render_vue_tag()} - % endif +

TODO: index page content

-<%def name="render_this_page_template()"> - ${parent.render_this_page_template()} - % if grid is not Undefined: - ${grid.render_vue_template()} - % endif - - -<%def name="finalize_this_page_vars()"> - ${parent.finalize_this_page_vars()} - % if grid is not Undefined: - - % endif - ${parent.body()} diff --git a/src/wuttaweb/templates/master/view.mako b/src/wuttaweb/templates/master/view.mako deleted file mode 100644 index b84ebc1..0000000 --- a/src/wuttaweb/templates/master/view.mako +++ /dev/null @@ -1,9 +0,0 @@ -## -*- coding: utf-8; -*- -<%inherit file="/master/form.mako" /> - -<%def name="title()">${index_title} » ${instance_title} - -<%def name="content_title()">${instance_title} - - -${parent.body()} diff --git a/src/wuttaweb/views/base.py b/src/wuttaweb/views/base.py index ccdc749..94e22b2 100644 --- a/src/wuttaweb/views/base.py +++ b/src/wuttaweb/views/base.py @@ -26,7 +26,7 @@ Base Logic for Views from pyramid import httpexceptions -from wuttaweb import forms, grids +from wuttaweb import forms class View: @@ -68,31 +68,11 @@ class View: Make and return a new :class:`~wuttaweb.forms.base.Form` instance, per the given ``kwargs``. - This is the "base" factory which merely invokes the - constructor. + This is the "default" form factory which merely invokes + the constructor. """ return forms.Form(self.request, **kwargs) - def make_grid(self, **kwargs): - """ - Make and return a new :class:`~wuttaweb.grids.base.Grid` - instance, per the given ``kwargs``. - - This is the "base" factory which merely invokes the - constructor. - """ - return grids.Grid(self.request, **kwargs) - - def make_grid_action(self, key, **kwargs): - """ - Make and return a new :class:`~wuttaweb.grids.base.GridAction` - instance, per the given ``key`` and ``kwargs``. - - This is the "base" factory which merely invokes the - constructor. - """ - return grids.GridAction(self.request, key, **kwargs) - def notfound(self): """ Convenience method, to raise a HTTP 404 Not Found exception:: diff --git a/src/wuttaweb/views/master.py b/src/wuttaweb/views/master.py index f884f7a..2cf719a 100644 --- a/src/wuttaweb/views/master.py +++ b/src/wuttaweb/views/master.py @@ -100,25 +100,6 @@ class MasterView(View): Code should not access this directly but instead call :meth:`get_model_title_plural()`. - .. attribute:: model_key - - Optional override for the view's "model key" - e.g. ``'id'`` - (string for simple case) or composite key such as - ``('id_field', 'name_field')``. - - If :attr:`model_class` is set to a SQLAlchemy mapped class, the - model key can be determined automatically. - - Code should not access this directly but instead call - :meth:`get_model_key()`. - - .. attribute:: grid_key - - Optional override for the view's grid key, e.g. ``'widgets'``. - - Code should not access this directly but instead call - :meth:`get_grid_key()`. - .. attribute:: config_title Optional override for the view's "config" title, e.g. ``"Wutta @@ -157,29 +138,6 @@ class MasterView(View): i.e. it should have an :meth:`index()` view. Default value is ``True``. - .. attribute:: has_grid - - Boolean indicating whether the :meth:`index()` view should - include a grid. Default value is ``True``. - - .. attribute:: grid_columns - - List of columns for the :meth:`index()` view grid. - - This is optional; see also :meth:`index_get_grid_columns()`. - - .. attribute:: viewable - - Boolean indicating whether the view model supports "viewing" - - i.e. it should have a :meth:`view()` view. Default value is - ``True``. - - .. attribute:: form_fields - - List of columns for the model form. - - This is optional; see also :meth:`get_form_fields()`. - .. attribute:: configurable Boolean indicating whether the master view supports @@ -193,13 +151,9 @@ class MasterView(View): # features listable = True - has_grid = True - viewable = True configurable = False # current action - listing = False - viewing = False configuring = False ############################## @@ -216,158 +170,12 @@ class MasterView(View): By default, this view is included only if :attr:`listable` is true. - - The default view logic will show a "grid" (table) with the - model data (unless :attr:`has_grid` is false). - - See also related methods, which are called by this one: - - * :meth:`index_make_grid()` """ - self.listing = True - context = { - 'index_url': None, # nb. avoid title link since this *is* the index + 'index_url': None, # avoid title link since this *is* the index } - - if self.has_grid: - context['grid'] = self.index_make_grid() - return self.render_to_response('index', context) - def index_make_grid(self, **kwargs): - """ - Create and return a :class:`~wuttaweb.grids.base.Grid` - instance for use with the :meth:`index()` view. - - See also related methods, which are called by this one: - - * :meth:`get_grid_key()` - * :meth:`index_get_grid_columns()` - * :meth:`index_get_grid_data()` - * :meth:`index_configure_grid()` - """ - if 'key' not in kwargs: - kwargs['key'] = self.get_grid_key() - - if 'columns' not in kwargs: - kwargs['columns'] = self.index_get_grid_columns() - - if 'data' not in kwargs: - kwargs['data'] = self.index_get_grid_data() - - if 'actions' not in kwargs: - actions = [] - - # TODO: should split this off into index_get_grid_actions() ? - if self.viewable: - actions.append(self.make_grid_action('view', icon='eye', - url=self.get_action_url_view)) - - kwargs['actions'] = actions - - grid = self.make_grid(**kwargs) - self.index_configure_grid(grid) - return grid - - def index_get_grid_columns(self): - """ - Returns the default list of grid column names, for the - :meth:`index()` view. - - This is called by :meth:`index_make_grid()`; in the resulting - :class:`~wuttaweb.grids.base.Grid` instance, this becomes - :attr:`~wuttaweb.grids.base.Grid.columns`. - - This method may return ``None``, in which case the grid may - (try to) generate its own default list. - - Subclass may define :attr:`grid_columns` for simple cases, or - can override this method if needed. - - Also note that :meth:`index_configure_grid()` may be used to - further modify the final column set, regardless of what this - method returns. So a common pattern is to declare all - "supported" columns by setting :attr:`grid_columns` but then - optionally remove or replace some of those within - :meth:`index_configure_grid()`. - """ - if hasattr(self, 'grid_columns'): - return self.grid_columns - - def index_get_grid_data(self): - """ - Returns the grid data for the :meth:`index()` view. - - This is called by :meth:`index_make_grid()`; in the resulting - :class:`~wuttaweb.grids.base.Grid` instance, this becomes - :attr:`~wuttaweb.grids.base.Grid.data`. - - As of now there is not yet a "sane" default for this method; - it simply returns an empty list. Subclass should override as - needed. - """ - return [] - - def get_action_url_view(self, obj, i): - """ - Returns the "view" grid action URL for the given object. - - Most typically this is like ``/widgets/XXX`` where ``XXX`` - represents the object's key/ID. - """ - route_prefix = self.get_route_prefix() - - kw = {} - for key in self.get_model_key(): - kw[key] = obj[key] - - return self.request.route_url(f'{route_prefix}.view', **kw) - - def index_configure_grid(self, grid): - """ - Configure the grid for the :meth:`index()` view. - - This is called by :meth:`index_make_grid()`. - - There is no default logic here; subclass should override as - needed. The ``grid`` param will already be "complete" and - ready to use as-is, but this method can further modify it - based on request details etc. - """ - - ############################## - # view methods - ############################## - - def view(self): - """ - View to "view" details of an existing model record. - - This usually corresponds to a URL like ``/widgets/XXX`` - where ``XXX`` represents the key/ID for the record. - - By default, this view is included only if :attr:`viewable` is - true. - - The default view logic will show a read-only form with field - values displayed. - - See also related methods, which are called by this one: - - * :meth:`make_model_form()` - """ - self.viewing = True - instance = self.get_instance() - form = self.make_model_form(instance, readonly=True) - - context = { - 'instance': instance, - 'instance_title': self.get_instance_title(instance), - 'form': form, - } - return self.render_to_response('view', context) - ############################## # configure methods ############################## @@ -643,12 +451,14 @@ class MasterView(View): Save the given settings to the DB; this is called by :meth:`configure()`. - This method expects a list of name/value dicts and will simply - save each to the DB, with no "conversion" logic. + This method expected a list of name/value dicts and will + simply save each to the DB, with no "conversion" logic. :param settings: List of normalized setting definitions, as returned by :meth:`configure_gather_settings()`. """ + # app = self.get_rattail_app() + # nb. must avoid self.Session here in case that does not point # to our primary app DB session = Session() @@ -660,6 +470,26 @@ class MasterView(View): # support methods ############################## + def get_index_title(self): + """ + Returns the main index title for the master view. + + By default this returns the value from + :meth:`get_model_title_plural()`. Subclass may override as + needed. + """ + return self.get_model_title_plural() + + def get_index_url(self, **kwargs): + """ + Returns the URL for master's :meth:`index()` view. + + NB. this returns ``None`` if :attr:`listable` is false. + """ + if self.listable: + route_prefix = self.get_route_prefix() + return self.request.route_url(route_prefix, **kwargs) + def render_to_response(self, template, context): """ Locate and render an appropriate template, with the given @@ -738,110 +568,6 @@ class MasterView(View): """ return [f'/master/{template}.mako'] - def get_index_title(self): - """ - Returns the main index title for the master view. - - By default this returns the value from - :meth:`get_model_title_plural()`. Subclass may override as - needed. - """ - return self.get_model_title_plural() - - def get_index_url(self, **kwargs): - """ - Returns the URL for master's :meth:`index()` view. - - NB. this returns ``None`` if :attr:`listable` is false. - """ - if self.listable: - route_prefix = self.get_route_prefix() - return self.request.route_url(route_prefix, **kwargs) - - def get_instance(self): - """ - This should return the "current" model instance based on the - request details (e.g. route kwargs). - - If the instance cannot be found, this should raise a HTTP 404 - exception, i.e. :meth:`~wuttaweb.views.base.View.notfound()`. - - There is no "sane" default logic here; subclass *must* - override or else a ``NotImplementedError`` is raised. - """ - raise NotImplementedError("you must define get_instance() method " - f" for view class: {self.__class__}") - - def get_instance_title(self, instance): - """ - Return the human-friendly "title" for the instance, to be used - in the page title when viewing etc. - - Default logic returns the value from ``str(instance)``; - subclass may override if needed. - """ - return str(instance) - - def make_model_form(self, model_instance=None, **kwargs): - """ - Create and return a :class:`~wuttaweb.forms.base.Form` - for the view model. - - Note that this method is called for multiple "CRUD" views, - e.g.: - - * :meth:`view()` - - See also related methods, which are called by this one: - - * :meth:`get_form_fields()` - * :meth:`configure_form()` - """ - kwargs['model_instance'] = model_instance - - if 'fields' not in kwargs: - kwargs['fields'] = self.get_form_fields() - - form = self.make_form(**kwargs) - self.configure_form(form) - return form - - def get_form_fields(self): - """ - Returns the initial list of field names for the model form. - - This is called by :meth:`make_model_form()`; in the resulting - :class:`~wuttaweb.forms.base.Form` instance, this becomes - :attr:`~wuttaweb.forms.base.Form.fields`. - - This method may return ``None``, in which case the form may - (try to) generate its own default list. - - Subclass may define :attr:`form_fields` for simple cases, or - can override this method if needed. - - Note that :meth:`configure_form()` may be used to further - modify the final field list, regardless of what this method - returns. So a common pattern is to declare all "supported" - fields by setting :attr:`form_fields` but then optionally - remove or replace some in :meth:`configure_form()`. - """ - if hasattr(self, 'form_fields'): - return self.form_fields - - def configure_form(self, form): - """ - Configure the given model form, as needed. - - This is called by :meth:`make_model_form()` - for multiple - CRUD views. - - There is no default logic here; subclass should override if - needed. The ``form`` param will already be "complete" and - ready to use as-is, but this method can further modify it - based on request details etc. - """ - ############################## # class methods ############################## @@ -937,32 +663,6 @@ class MasterView(View): model_title = cls.get_model_title() return f"{model_title}s" - @classmethod - def get_model_key(cls): - """ - Returns the "model key" for the master view. - - This should return a tuple containing one or more "field - names" corresponding to the primary key for data records. - - In the most simple/common scenario, where the master view - represents a Wutta-based SQLAlchemy model, the return value - for this method is: ``('uuid',)`` - - But there is no "sane" default for other scenarios, in which - case subclass should define :attr:`model_key`. If the model - key cannot be determined, raises ``AttributeError``. - - :returns: Tuple of field names comprising the model key. - """ - if hasattr(cls, 'model_key'): - keys = cls.model_key - if isinstance(keys, str): - keys = [keys] - return tuple(keys) - - raise AttributeError(f"you must define model_key for view class: {cls}") - @classmethod def get_route_prefix(cls): """ @@ -1013,27 +713,6 @@ class MasterView(View): route_prefix = cls.get_route_prefix() return f'/{route_prefix}' - @classmethod - def get_instance_url_prefix(cls): - """ - Generate the URL prefix specific to an instance for this model - view. This will include model key param placeholders; it - winds up looking like: - - * ``/widgets/{uuid}`` - * ``/resources/{foo}|{bar}|{baz}`` - - The former being the most simple/common, and the latter - showing what a "composite" model key looks like, with pipe - symbols separating the key parts. - """ - prefix = cls.get_url_prefix() + '/' - for i, key in enumerate(cls.get_model_key()): - if i: - prefix += '|' - prefix += f'{{{key}}}' - return prefix - @classmethod def get_template_prefix(cls): """ @@ -1059,26 +738,6 @@ class MasterView(View): return cls.get_url_prefix() - @classmethod - def get_grid_key(cls): - """ - Returns the (presumably) unique key to be used for the primary - grid in the :meth:`index()` view. This key may also be used - as the basis (key prefix) for secondary grids. - - This is called from :meth:`index_make_grid()`; in the - resulting :class:`~wuttaweb.grids.base.Grid` instance, this - becomes :attr:`~wuttaweb.grids.base.Grid.key`. - - The default logic for this method will call - :meth:`get_route_prefix()` and return that value as-is. A - subclass may override by assigning :attr:`grid_key`. - """ - if hasattr(cls, 'grid_key'): - return cls.grid_key - - return cls.get_route_prefix() - @classmethod def get_config_title(cls): """ @@ -1135,13 +794,6 @@ class MasterView(View): config.add_view(cls, attr='index', route_name=route_prefix) - # view - if cls.viewable: - instance_url_prefix = cls.get_instance_url_prefix() - config.add_route(f'{route_prefix}.view', instance_url_prefix) - config.add_view(cls, attr='view', - route_name=f'{route_prefix}.view') - # configure if cls.configurable: config.add_route(f'{route_prefix}.configure', diff --git a/src/wuttaweb/views/settings.py b/src/wuttaweb/views/settings.py index 1082287..bfe6830 100644 --- a/src/wuttaweb/views/settings.py +++ b/src/wuttaweb/views/settings.py @@ -26,11 +26,8 @@ Views for app settings from collections import OrderedDict -from wuttjamaican.db.model import Setting - from wuttaweb.views import MasterView from wuttaweb.util import get_libver, get_liburl -from wuttaweb.db import Session class AppInfoView(MasterView): @@ -41,16 +38,10 @@ class AppInfoView(MasterView): * ``/appinfo/`` * ``/appinfo/configure`` - - See also :class:`SettingView`. """ model_name = 'AppInfo' model_title_plural = "App Info" route_prefix = 'appinfo' - has_grid = False - viewable = False - editable = False - deletable = False configurable = True def configure_get_simple_settings(self): @@ -112,6 +103,8 @@ class AppInfoView(MasterView): ('bb_vue_fontawesome', "(BB) @fortawesome/vue-fontawesome"), ]) + # import ipdb; ipdb.set_trace() + for key in weblibs: title = weblibs[key] weblibs[key] = { @@ -134,79 +127,12 @@ class AppInfoView(MasterView): return context -class SettingView(MasterView): - """ - Master view for the "raw" settings table. - - Notable URLs provided by this class: - - * ``/settings/`` - - See also :class:`AppInfoView`. - """ - model_class = Setting - model_title = "Raw Setting" - - # TODO: this should be deduced by master - model_key = 'name' - - # TODO: try removing these - grid_columns = [ - 'name', - 'value', - ] - form_fields = list(grid_columns) - - # TODO: should define query, let master handle the rest - def index_get_grid_data(self, session=None): - """ """ - model = self.app.model - - session = session or Session() - query = session.query(model.Setting)\ - .order_by(model.Setting.name) - - settings = [] - for setting in query: - settings.append(self.normalize_setting(setting)) - - return settings - - # TODO: master should handle this (but not as dict) - def normalize_setting(self, setting): - """ """ - return { - 'name': setting.name, - 'value': setting.value, - } - - # TODO: master should handle this - def get_instance(self, session=None): - """ """ - model = self.app.model - session = session or Session() - name = self.request.matchdict['name'] - setting = session.query(model.Setting).get(name) - if setting: - return self.normalize_setting(setting) - - return self.notfound() - - # TODO: master should handle this - def get_instance_title(self, setting): - """ """ - return setting['name'] - - def defaults(config, **kwargs): base = globals() AppInfoView = kwargs.get('AppInfoView', base['AppInfoView']) AppInfoView.defaults(config) - SettingView = kwargs.get('SettingView', base['SettingView']) - SettingView.defaults(config) - def includeme(config): defaults(config) diff --git a/tests/forms/test_base.py b/tests/forms/test_base.py index 5270f0f..5e29ad6 100644 --- a/tests/forms/test_base.py +++ b/tests/forms/test_base.py @@ -59,8 +59,8 @@ class TestForm(TestCase): def tearDown(self): testing.tearDown() - def make_form(self, **kwargs): - return base.Form(self.request, **kwargs) + def make_form(self, request=None, **kwargs): + return base.Form(request or self.request, **kwargs) def make_schema(self): schema = colander.Schema(children=[ @@ -124,33 +124,19 @@ class TestForm(TestCase): self.assertIs(form.schema, schema) self.assertIs(form.get_schema(), schema) - # schema is auto-generated if fields provided + # auto-generating schema not yet supported form = self.make_form(fields=['foo', 'bar']) - schema = form.get_schema() - self.assertEqual(len(schema.children), 2) - self.assertEqual(schema['foo'].name, 'foo') - - # but auto-generating without fields is not supported - form = self.make_form() self.assertIsNone(form.schema) self.assertRaises(NotImplementedError, form.get_schema) def test_get_deform(self): schema = self.make_schema() - - # basic form = self.make_form(schema=schema) self.assertFalse(hasattr(form, 'deform_form')) dform = form.get_deform() self.assertIsInstance(dform, deform.Form) self.assertIs(form.deform_form, dform) - # with model instance / cstruct - myobj = {'foo': 'one', 'bar': 'two'} - form = self.make_form(schema=schema, model_instance=myobj) - dform = form.get_deform() - self.assertEqual(dform.cstruct, myobj) - def test_get_label(self): form = self.make_form(fields=['foo', 'bar']) self.assertEqual(form.get_label('foo'), "Foo") @@ -207,13 +193,6 @@ class TestForm(TestCase): # nb. no error message self.assertNotIn('message', html) - # readonly - html = form.render_vue_field('foo', readonly=True) - self.assertIn('', html) - self.assertNotIn('') - - def test_render_vue_template(self): - self.pyramid_config.include('pyramid_mako') - self.pyramid_config.add_subscriber('wuttaweb.subscribers.before_render', - 'pyramid.events.BeforeRender') - - grid = self.make_grid(columns=['foo', 'bar']) - html = grid.render_vue_template() - self.assertIn('