feat: add first wutta-based master, for PersonView

still opt-in-only at this point, the traditional tailbone-native
master is used by default.

new wutta master is not feature complete yet.  but at least things
seem to render and form posts work okay..

when enabled, this uses a "completely" wutta-based stack for the view,
grid and forms.  but the underlying DB is of course rattail, and the
templates are still traditional/tailbone.
This commit is contained in:
Lance Edgar 2024-08-15 16:05:53 -05:00
parent a6ce5eb21d
commit dd176a5e9e
7 changed files with 173 additions and 1 deletions

View file

@ -2187,4 +2187,8 @@ def defaults(config, **kwargs):
def includeme(config):
defaults(config)
wutta_config = config.registry.settings['wutta_config']
if wutta_config.get_bool('tailbone.use_wutta_views', default=False, usedb=False):
config.include('tailbone.views.wutta.people')
else:
defaults(config)

View file

View file

@ -0,0 +1,102 @@
# -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail 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.
#
# Rattail 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
# Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Person Views
"""
from rattail.db.model import Person
from wuttaweb.views import people as wutta
from tailbone.views import people as tailbone
from tailbone.db import Session
class PersonView(wutta.PersonView):
"""
This is the first attempt at blending newer Wutta views with
legacy Tailbone config.
So, this is a Wutta-based view but it should be included by a
Tailbone app configurator.
"""
model_class = Person
Session = Session
# labels = {
# 'display_name': "Full Name",
# }
grid_columns = [
'display_name',
'first_name',
'last_name',
'phone',
'email',
'merge_requested',
]
form_fields = [
'first_name',
'middle_name',
'last_name',
'display_name',
'default_phone',
'default_email',
# 'address',
# 'employee',
'customers',
# 'members',
'users',
]
def get_query(self, session=None):
""" """
model = self.app.model
session = session or self.Session()
return session.query(model.Person)\
.order_by(model.Person.display_name)
def configure_form(self, f):
""" """
super().configure_form(f)
# default_phone
f.set_required('default_phone', False)
# default_email
f.set_required('default_email', False)
# customers
if self.creating or self.editing:
f.remove('customers')
def defaults(config, **kwargs):
base = globals()
kwargs.setdefault('PersonView', base['PersonView'])
tailbone.defaults(config, **kwargs)
def includeme(config):
defaults(config)

View file

@ -43,6 +43,8 @@ class WebTestCase(DataTestCase):
'tailbone.app.add_index_page')
self.pyramid_config.add_directive('add_tailbone_model_view',
'tailbone.app.add_model_view')
self.pyramid_config.add_directive('add_tailbone_config_page',
'tailbone.app.add_config_page')
self.pyramid_config.add_subscriber('tailbone.subscribers.before_render',
'pyramid.events.BeforeRender')
self.pyramid_config.include('tailbone.static')

View file

@ -0,0 +1,17 @@
# -*- coding: utf-8; -*-
from tailbone.views import users as mod
from tests.util import WebTestCase
class TestPersonView(WebTestCase):
def make_view(self):
return mod.PersonView(self.request)
def test_includeme(self):
self.pyramid_config.include('tailbone.views.people')
def test_includeme_wutta(self):
self.config.setdefault('tailbone.use_wutta_views', 'true')
self.pyramid_config.include('tailbone.views.people')

View file

View file

@ -0,0 +1,47 @@
# -*- coding: utf-8; -*-
from unittest.mock import patch
from sqlalchemy import orm
from tailbone.views.wutta import people as mod
from tests.util import WebTestCase
class TestPersonView(WebTestCase):
def make_view(self):
return mod.PersonView(self.request)
def test_includeme(self):
self.pyramid_config.include('tailbone.views.wutta.people')
def test_get_query(self):
view = self.make_view()
# sanity / coverage check
query = view.get_query(session=self.session)
self.assertIsInstance(query, orm.Query)
def test_configure_form(self):
model = self.app.model
barney = model.User(username='barney')
self.session.add(barney)
self.session.commit()
view = self.make_view()
# customers field remains when viewing
with patch.object(view, 'viewing', new=True):
form = view.make_form(model_instance=barney,
fields=view.get_form_fields())
self.assertIn('customers', form.fields)
view.configure_form(form)
self.assertIn('customers', form)
# customers field removed when editing
with patch.object(view, 'editing', new=True):
form = view.make_form(model_instance=barney,
fields=view.get_form_fields())
self.assertIn('customers', form.fields)
view.configure_form(form)
self.assertNotIn('customers', form)