2
0
Fork 0

Compare commits

...

3 commits

Author SHA1 Message Date
Lance Edgar dce91a3a96 bump: version 0.10.0 → 0.10.1 2024-08-19 12:00:46 -05:00
Lance Edgar 1efaca4e52 fix: make util.get_model_fields() work with more model classes
should not restrict to classes inheriting from wuttjamaican base, any
sqlalchemy class should work
2024-08-19 11:48:52 -05:00
Lance Edgar 4643aa3e3c docs: various improvements to docs, per dust settling 2024-08-19 11:47:21 -05:00
9 changed files with 58 additions and 37 deletions

View file

@ -5,6 +5,12 @@ All notable changes to wuttaweb will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## v0.10.1 (2024-08-19)
### Fix
- make `util.get_model_fields()` work with more model classes
## v0.10.0 (2024-08-18) ## v0.10.0 (2024-08-18)
### Feat ### Feat

View file

@ -6,7 +6,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "WuttaWeb" name = "WuttaWeb"
version = "0.10.0" version = "0.10.1"
description = "Web App for Wutta Framework" description = "Web App for Wutta Framework"
readme = "README.md" readme = "README.md"
authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]

View file

@ -150,7 +150,7 @@ class WuttaSecurityPolicy:
return auth.has_permission(self.db_session, user, permission) return auth.has_permission(self.db_session, user, permission)
def add_permission_group(pyramid_config, key, label=None, overwrite=True): def add_permission_group(pyramid_config, groupkey, label=None, overwrite=True):
""" """
Pyramid directive to add a "permission group" to the app's Pyramid directive to add a "permission group" to the app's
awareness. awareness.
@ -169,12 +169,12 @@ def add_permission_group(pyramid_config, key, label=None, overwrite=True):
pyramid_config.add_permission_group('widgets', label="Widgets") pyramid_config.add_permission_group('widgets', label="Widgets")
:param key: Unique key for the permission group. In the context :param groupkey: Unique key for the permission group. In the
of a master view, this will be the same as context of a master view, this will be the same as
:attr:`~wuttaweb.views.master.MasterView.permission_prefix`. :attr:`~wuttaweb.views.master.MasterView.permission_prefix`.
:param label: Optional label for the permission group. If not :param label: Optional label for the permission group. If not
specified, it is derived from ``key``. specified, it is derived from ``groupkey``.
:param overwrite: If the permission group was already established, :param overwrite: If the permission group was already established,
this flag controls whether the group's label should be this flag controls whether the group's label should be
@ -186,9 +186,9 @@ def add_permission_group(pyramid_config, key, label=None, overwrite=True):
app = config.get_app() app = config.get_app()
def action(): def action():
perms = pyramid_config.get_settings().get('wutta_permissions', {}) perms = pyramid_config.get_settings().get('wutta_permissions', {})
if overwrite or key not in perms: if overwrite or groupkey not in perms:
group = perms.setdefault(key, {'key': key}) group = perms.setdefault(groupkey, {'key': groupkey})
group['label'] = label or app.make_title(key) group['label'] = label or app.make_title(groupkey)
pyramid_config.add_settings({'wutta_permissions': perms}) pyramid_config.add_settings({'wutta_permissions': perms})
pyramid_config.action(None, action) pyramid_config.action(None, action)
@ -215,8 +215,8 @@ def add_permission(pyramid_config, groupkey, key, label=None):
pyramid_config.add_permission('widgets', 'widgets.polish', pyramid_config.add_permission('widgets', 'widgets.polish',
label="Polish all the widgets") label="Polish all the widgets")
:param key: Unique key for the permission group. In the context :param groupkey: Unique key for the permission group. In the
of a master view, this will be the same as context of a master view, this will be the same as
:attr:`~wuttaweb.views.master.MasterView.permission_prefix`. :attr:`~wuttaweb.views.master.MasterView.permission_prefix`.
:param key: Unique key for the permission. This should be the :param key: Unique key for the permission. This should be the

View file

@ -182,6 +182,8 @@ class Form:
String name for Vue component tag. By default this is String name for Vue component tag. By default this is
``'wutta-form'``. See also :meth:`render_vue_tag()`. ``'wutta-form'``. See also :meth:`render_vue_tag()`.
See also :attr:`vue_component`.
.. attribute:: align_buttons_right .. attribute:: align_buttons_right
Flag indicating whether the buttons (submit, cancel etc.) Flag indicating whether the buttons (submit, cancel etc.)
@ -784,6 +786,13 @@ class Form:
</form> </form>
</script> </script>
<script>
WuttaFormData = {}
WuttaForm = {
template: 'wutta-form-template',
}
</script>
.. todo:: .. todo::
Why can't Sphinx render the above code block as 'html' ? Why can't Sphinx render the above code block as 'html' ?

View file

@ -86,9 +86,9 @@ class Grid:
.. attribute:: columns .. attribute:: columns
:class:`~wuttaweb.forms.base.FieldList` instance containing :class:`~wuttaweb.util.FieldList` instance containing string
string column names for the grid. Columns will appear in the column names for the grid. Columns will appear in the same
same order as they are in this list. order as they are in this list.
See also :meth:`set_columns()` and :meth:`get_columns()`. See also :meth:`set_columns()` and :meth:`get_columns()`.
@ -239,9 +239,9 @@ class Grid:
.. attribute:: paginated .. attribute:: paginated
Boolean indicating whether the grid data should be paginated Boolean indicating whether the grid data should be paginated,
vs. all data shown at once. Default is ``False`` which means i.e. split up into pages. Default is ``False`` which means all
the full set of grid data is sent for each request. data is shown at once.
See also :attr:`pagesize` and :attr:`page`, and See also :attr:`pagesize` and :attr:`page`, and
:attr:`paginate_on_backend`. :attr:`paginate_on_backend`.
@ -392,7 +392,7 @@ class Grid:
Explicitly set the list of grid columns. Explicitly set the list of grid columns.
This will overwrite :attr:`columns` with a new This will overwrite :attr:`columns` with a new
:class:`~wuttaweb.forms.base.FieldList` instance. :class:`~wuttaweb.util.FieldList` instance.
:param columns: List of string column names. :param columns: List of string column names.
""" """
@ -440,9 +440,8 @@ class Grid:
:param label: New label for the column header. :param label: New label for the column header.
See also :meth:`get_label()`. See also :meth:`get_label()`. Label overrides are tracked via
:attr:`labels`.
Label overrides are tracked via :attr:`labels`.
""" """
self.labels[key] = label self.labels[key] = label
@ -490,7 +489,7 @@ class Grid:
def render_foo(record, key, value): def render_foo(record, key, value):
return HTML.literal("<p>this is the final cell value</p>") return HTML.literal("<p>this is the final cell value</p>")
grid = Grid(columns=['foo', 'bar']) grid = Grid(request, columns=['foo', 'bar'])
grid.set_renderer('foo', render_foo) grid.set_renderer('foo', render_foo)
Renderer overrides are tracked via :attr:`renderers`. Renderer overrides are tracked via :attr:`renderers`.
@ -509,8 +508,8 @@ class Grid:
URL for this will be the same as for the "View" URL for this will be the same as for the "View"
:class:`GridAction` :class:`GridAction`
(aka. :meth:`~wuttaweb.views.master.MasterView.view()`). (aka. :meth:`~wuttaweb.views.master.MasterView.view()`).
Although of course each cell gets a different link depending Although of course each cell in the column gets a different
on which data record it points to. link depending on which data record it points to.
It is typical to enable auto-link for fields relating to ID, It is typical to enable auto-link for fields relating to ID,
description etc. or some may prefer to auto-link all columns. description etc. or some may prefer to auto-link all columns.
@ -609,8 +608,8 @@ class Grid:
The term "model property" is a bit technical, an example The term "model property" is a bit technical, an example
should help to clarify:: should help to clarify::
model = self.app.model model = app.model
grid = Grid(self.request, model_class=model.Person) grid = Grid(request, model_class=model.Person)
# explicit property # explicit property
sorter = grid.make_sorter(model.Person.full_name) sorter = grid.make_sorter(model.Person.full_name)
@ -633,7 +632,7 @@ class Grid:
] ]
# nb. no model_class, just as an example # nb. no model_class, just as an example
grid = Grid(self.request, columns=['foo', 'bar'], data=data) grid = Grid(request, columns=['foo', 'bar'], data=data)
def getkey(obj): def getkey(obj):
if obj.get('foo') if obj.get('foo')
@ -725,8 +724,8 @@ class Grid:
A backend sorter callable must accept ``(data, direction)`` A backend sorter callable must accept ``(data, direction)``
args and return the sorted data/query, for example:: args and return the sorted data/query, for example::
model = self.app.model model = app.model
grid = Grid(self.request, model_class=model.Person) grid = Grid(request, model_class=model.Person)
def sort_full_name(query, direction): def sort_full_name(query, direction):
sortspec = getattr(model.Person.full_name, direction) sortspec = getattr(model.Person.full_name, direction)
@ -750,6 +749,10 @@ class Grid:
""" """
Remove the backend sorter for a column. Remove the backend sorter for a column.
Note that this removes the sorter *function*, so there is
no way to sort by this column unless another sorter is
later defined for it.
See also :meth:`set_sorter()`. See also :meth:`set_sorter()`.
""" """
self.sorters.pop(key, None) self.sorters.pop(key, None)
@ -1140,6 +1143,7 @@ class Grid:
See also these methods which may be called by this one: See also these methods which may be called by this one:
* :meth:`sort_data()`
* :meth:`paginate_data()` * :meth:`paginate_data()`
""" """
data = self.data or [] data = self.data or []
@ -1283,6 +1287,7 @@ class Grid:
{ {
'field': 'foo', 'field': 'foo',
'label': "Foo", 'label': "Foo",
'sortable': True,
} }
See also :meth:`get_vue_data()`. See also :meth:`get_vue_data()`.

View file

@ -462,14 +462,13 @@ def get_model_fields(config, model_class=None):
if not model_class: if not model_class:
return return
app = config.get_app() try:
model = app.model mapper = sa.inspect(model_class)
if not issubclass(model_class, model.Base): except sa.exc.NoInspectionAvailable:
return pass
else:
mapper = sa.inspect(model_class) fields = [prop.key for prop in mapper.iterate_properties]
fields = [prop.key for prop in mapper.iterate_properties] return fields
return fields
def make_json_safe(value, key=None, warn=True): def make_json_safe(value, key=None, warn=True):

View file

@ -259,7 +259,7 @@ class MasterView(View):
.. attribute:: form_fields .. attribute:: form_fields
List of columns for the model form. List of fields for the model form.
This is optional; see also :meth:`get_form_fields()`. This is optional; see also :meth:`get_form_fields()`.

View file

@ -101,6 +101,7 @@ class PersonView(MasterView):
@classmethod @classmethod
def defaults(cls, config): def defaults(cls, config):
""" """
cls._defaults(config) cls._defaults(config)
cls._people_defaults(config) cls._people_defaults(config)

View file

@ -246,6 +246,7 @@ class RoleView(MasterView):
@classmethod @classmethod
def defaults(cls, config): def defaults(cls, config):
""" """
cls._defaults(config) cls._defaults(config)
cls._role_defaults(config) cls._role_defaults(config)