From 2f048b45c99a6d285fda4c9c8d031fdfa07ec704 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 2 Feb 2019 20:30:35 -0600 Subject: [PATCH] Improve user form handling, to prevent unwanted Person creation i.e. only create new person if name(s) were provided --- tailbone/views/users.py | 56 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/tailbone/views/users.py b/tailbone/views/users.py index 8eebb32e..be979dd7 100644 --- a/tailbone/views/users.py +++ b/tailbone/views/users.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2018 Lance Edgar +# Copyright © 2010-2019 Lance Edgar # # This file is part of Rattail. # @@ -63,9 +63,9 @@ class UsersView(PrincipalMasterView): form_fields = [ 'username', 'person', - 'first_name', - 'last_name', - 'display_name', + 'first_name_', + 'last_name_', + 'display_name_', 'active', 'active_sticky', 'set_password', @@ -170,6 +170,18 @@ class UsersView(PrincipalMasterView): field_display=person_display, service_url=people_url)) f.set_label('person_uuid', "Person") + # person name(s) + if self.editing: + # must explicitly set default, for "custom" field names + f.set_default('first_name_', user.first_name or "") + f.set_default('last_name_', user.last_name or "") + f.set_default('display_name_', user.display_name or "") + elif not self.creating: + # must provide custom renderer as well + f.set_renderer('first_name_', self.render_person_name) + f.set_renderer('last_name_', self.render_person_name) + f.set_renderer('display_name_', self.render_person_name) + # set_password f.set_widget('set_password', dfwidget.CheckedPasswordWidget()) # if self.creating: @@ -218,10 +230,38 @@ class UsersView(PrincipalMasterView): .order_by(model.Role.name) def objectify(self, form, data): + + # create/update user as per normal + if data is None: + data = form.validated user = super(UsersView, self).objectify(form, data) + + # create/update person as needed + names = {} + if 'first_name_' in form: + names['first'] = data['first_name_'] + if 'last_name_' in form: + names['last'] = data['last_name_'] + if 'display_name_' in form: + names['display'] = data['display_name_'] + # note, do *not* create new person unless name(s) provided + if not user.person and any([n for n in names.values()]): + user.person = model.Person() + if user.person: + if 'first' in names: + user.person.first_name = names['first'] + if 'last' in names: + user.person.last_name = names['last'] + if 'display' in names: + user.person.display_name = names['display'] + + # maybe set user password if data['set_password']: set_user_password(user, data['set_password']) + + # update roles for user self.update_roles(user, data) + return user def update_roles(self, user, data): @@ -243,6 +283,14 @@ class UsersView(PrincipalMasterView): url = self.request.route_url('people.view', uuid=person.uuid) return tags.link_to(person, url) + def render_person_name(self, user, field): + if not field.endswith('_'): + return "" + name = getattr(user, field[:-1], None) + if not name: + return "" + return six.text_type(name) + def render_roles(self, user, field): roles = user.roles items = []