Source code for wuttaweb.views.people

# -*- coding: utf-8; -*-
################################################################################
#
#  wuttaweb -- Web App for Wutta Framework
#  Copyright © 2024-2026 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 <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Views for people
"""

import sqlalchemy as sa

from wuttjamaican.db.model import Person
from wuttaweb.views import MasterView
from wuttaweb.util import make_users_grid


[docs] class PersonView(MasterView): # pylint: disable=abstract-method """ Master view for people. Default route prefix is ``people``. Notable URLs provided by this class: * ``/people/`` * ``/people/new`` * ``/people/XXX`` * ``/people/XXX/edit`` * ``/people/XXX/delete`` """ model_class = Person model_title_plural = "People" route_prefix = "people" sort_defaults = "full_name" has_autocomplete = True grid_columns = [ "full_name", "first_name", "middle_name", "last_name", ] filter_defaults = { "full_name": {"active": True}, } form_fields = [ "full_name", "first_name", "middle_name", "last_name", "users", ] mergeable = True merge_additive_fields = ["usernames"] def configure_grid(self, grid): # pylint: disable=empty-docstring """ """ g = grid super().configure_grid(g) # full_name g.set_link("full_name") # first_name g.set_link("first_name") # last_name g.set_link("last_name") def configure_form(self, form): # pylint: disable=empty-docstring """ """ f = form super().configure_form(f) person = f.model_instance # full_name if self.creating or self.editing: f.remove("full_name") # users if self.creating or self.editing: f.remove("users") else: f.set_grid("users", self.make_users_grid(person))
[docs] def make_users_grid(self, person): """ Make and return the grid for the Users field. This grid is shown for the Users field when viewing a Person. :returns: Fully configured :class:`~wuttaweb.grids.base.Grid` instance. """ return make_users_grid( self.request, route_prefix=self.get_route_prefix(), data=person.users, columns=[ "username", "active", ], )
def objectify(self, form): # pylint: disable=empty-docstring """ """ person = super().objectify(form) # full_name person.full_name = self.app.make_full_name(person.first_name, person.last_name) return person def merge_get_data(self, obj): # pylint: disable=empty-docstring """ """ person = obj data = super().merge_get_data(person) data["usernames"] = sorted([u.username for u in person.users]) return data
[docs] def merge_execute(self, removing, keeping): """ We override default merge logic to re-assign users if needed. See also parent method: :meth:`~wuttaweb.views.master.MasterView.merge_execute()` """ session = self.Session() # reassign users for user in list(removing.users): user.person = keeping session.flush() # continue default merge super().merge_execute(removing, keeping)
def autocomplete_query(self, term): # pylint: disable=empty-docstring """ """ model = self.app.model session = self.Session() query = session.query(model.Person) criteria = [model.Person.full_name.ilike(f"%{word}%") for word in term.split()] query = query.filter(sa.and_(*criteria)).order_by(model.Person.full_name) return query def view_profile(self, session=None): # pylint: disable=empty-docstring """ """ person = self.get_instance(session=session) context = { "person": person, "instance": person, } return self.render_to_response("view_profile", context) def make_user(self): # pylint: disable=empty-docstring """ """ self.request.session.flash("TODO: this feature is not yet supported", "error") return self.redirect(self.request.get_referrer()) @classmethod def defaults(cls, config): # pylint: disable=empty-docstring """ """ # nb. Person may come from custom model wutta_config = config.registry.settings["wutta_config"] app = wutta_config.get_app() cls.model_class = app.model.Person cls._defaults(config) cls._people_defaults(config) @classmethod def _people_defaults(cls, config): route_prefix = cls.get_route_prefix() url_prefix = cls.get_url_prefix() instance_url_prefix = cls.get_instance_url_prefix() permission_prefix = cls.get_permission_prefix() # view profile config.add_route( f"{route_prefix}.view_profile", f"{instance_url_prefix}/profile", request_method="GET", ) config.add_view( cls, attr="view_profile", route_name=f"{route_prefix}.view_profile", permission=f"{permission_prefix}.view_profile", ) # make user for person config.add_route( f"{route_prefix}.make_user", f"{url_prefix}/make-user", request_method="POST", ) config.add_view( cls, attr="make_user", route_name=f"{route_prefix}.make_user", permission="users.create", )
def defaults(config, **kwargs): # pylint: disable=missing-function-docstring base = globals() PersonView = kwargs.get( # pylint: disable=invalid-name,redefined-outer-name "PersonView", base["PersonView"] ) PersonView.defaults(config) def includeme(config): # pylint: disable=missing-function-docstring defaults(config)