You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replace users profiles to a more traditional data/view model instead of using a GovReady-Q questionnaire to create the user profiles. The latter is adding complexity for accessing information about the users.
Below are notes from @JoshData on making the change.
What is the User Profile Module
Currently, a handful of user profile fields are stored in a compliance app. The app's name is account and it is stored in the govready-q repository in modules/system/account. It is one of the two compliance apps stored in modules/system (the other is the organization profile app) that are loaded during database initialization by the load_modules management command. (So once both are deleted, the load_modules management command can be retired.)
What it means to store the fields in the compliance app is that each user implicitly starts an instance of the "account" app on first use (creating Project, Task, TaskAnswer, and TaskAnswerHistory objects). The Project objects that hold account apps are indicated by the Project.is_account_project field being set to true. Each user is the admin (via ProjectMembership) of at most one Project whose is_account_project field is true. The user profile page is just answering questions in this app. And special getter functions in the User model (in siteapp/models.py) implement extracting these answers from those model objects.
What Fields Are Stored in the User Profile Module
Based on the functions in the User model (siteapp/models.py), the fields stored in the user profile module that we actually use on the site are name and profile photo. Not much. There are other questions in the compliance app (role, title, chat): I don't think role, title, and chat are accessed anywhere, and if they are, it wouldn't be important. (It's possible there are other hidden uses of this user data because the information is also returned in a dict by User.render_context_dict(), so you may need to check where that method is used in case there are other accesses to user profile answers, but it's probably not worth the time to dig around.)
Creating Model Fields
name can easily be added as a new field on the User model and the name method on the User model can be removed, and code referencing the name method can be updated to use the field directly. (User.name_and_email would also need to be adjusted.)
The profile photo can be moved to the model too. The normal Django way would be to use a FileField (not to be confused with another class of the same name used in Django forms); however, I have always found these fields and Django's "storage" backend system quite difficult to use. GovReady-Q is actually using a storage backend that I wrote called dbstorage. User.get_profile_picture_absolute_url would need to be updated to return a URL that serves the profile photo.
The existing getter methods can be used to write a migration to pull the existing profile data and store it in User model fields.
Removing Getter Methods
User.preload_profiles, preload_profile, user_settings_task_create_if_doesnt_exist, _get_setting, get_account_project, get_account_project_, and get_settings_task model methods could all be deleted. User.render_context_dict would need to be updated to get the name from a new model field. User.preload_profiles and preload_profile were added to optimize database queries but would likely not be necessary if the information is stored on the User model directly --- they can be deleted, and but they are referenced elsewhere in govready-q and those locations would need to be updated, probably by just deleting the calls to these functions. Some of the other methods (listed at the start of this paragraph) are used elsewhere in govready-q but likely also in ways that wouldn't be relevant once the user profile module is removed. You will need to grep the source code for each method name and figure out what to do, but it will likely be simply deleting code that references these methods.
Removing the Compliance App
Once the user profile data is stored elsewhere, the defunct database records for the user profile module can be deleted. Locate all of the Projects whose is_account_project field is true and delete all of the associated Task, TaskAnswer, and TaskAnswerHistory records, and the Project itself. Possibly equivalently, locate all AppVersion instances for the "account" compliance app in the AppSource whose "is_system_source" field is true, and delete any associated Tasks etc.
Once this is done the is_account_project field will be defunct and can be removed in a migration. All AppVersion instances in the database that are for the user profile module can be deleted. Lastly, the modules/system/account directory can be deleted.
This commit does most of the work of replacing
the account settings (profile) implemented as a compliance app
to a traditional account setting.
Add 'name' field to siteapp.models.User.
Created new account settings rout, view, and form.
Updated references to account info.
See ticket #633 for more information.
#633
Replace users profiles to a more traditional data/view model instead of using a GovReady-Q questionnaire to create the user profiles. The latter is adding complexity for accessing information about the users.
Below are notes from @JoshData on making the change.
What is the User Profile Module
Currently, a handful of user profile fields are stored in a compliance app. The app's name is
account
and it is stored in the govready-q repository inmodules/system/account
. It is one of the two compliance apps stored inmodules/system
(the other is the organization profile app) that are loaded during database initialization by theload_modules
management command. (So once both are deleted, theload_modules
management command can be retired.)What it means to store the fields in the compliance app is that each user implicitly starts an instance of the "account" app on first use (creating
Project
,Task
,TaskAnswer
, andTaskAnswerHistory
objects). The Project objects that hold account apps are indicated by theProject.is_account_project
field being set to true. Each user is the admin (viaProjectMembership
) of at most one Project whoseis_account_project
field is true. The user profile page is just answering questions in this app. And special getter functions in the User model (insiteapp/models.py
) implement extracting these answers from those model objects.What Fields Are Stored in the User Profile Module
Based on the functions in the User model (
siteapp/models.py
), the fields stored in the user profile module that we actually use on the site are name and profile photo. Not much. There are other questions in the compliance app (role, title, chat): I don't think role, title, and chat are accessed anywhere, and if they are, it wouldn't be important. (It's possible there are other hidden uses of this user data because the information is also returned in a dict byUser.render_context_dict()
, so you may need to check where that method is used in case there are other accesses to user profile answers, but it's probably not worth the time to dig around.)Creating Model Fields
name
can easily be added as a new field on the User model and thename
method on the User model can be removed, and code referencing thename
method can be updated to use the field directly. (User.name_and_email
would also need to be adjusted.)The profile photo can be moved to the model too. The normal Django way would be to use a FileField (not to be confused with another class of the same name used in Django forms); however, I have always found these fields and Django's "storage" backend system quite difficult to use. GovReady-Q is actually using a storage backend that I wrote called
dbstorage
.User.get_profile_picture_absolute_url
would need to be updated to return a URL that serves the profile photo.The existing getter methods can be used to write a migration to pull the existing profile data and store it in User model fields.
Removing Getter Methods
User.preload_profiles
,preload_profile
,user_settings_task_create_if_doesnt_exist
,_get_setting
,get_account_project
,get_account_project_
, andget_settings_task
model methods could all be deleted.User.render_context_dict
would need to be updated to get the name from a new model field.User.preload_profiles
andpreload_profile
were added to optimize database queries but would likely not be necessary if the information is stored on the User model directly --- they can be deleted, and but they are referenced elsewhere in govready-q and those locations would need to be updated, probably by just deleting the calls to these functions. Some of the other methods (listed at the start of this paragraph) are used elsewhere in govready-q but likely also in ways that wouldn't be relevant once the user profile module is removed. You will need to grep the source code for each method name and figure out what to do, but it will likely be simply deleting code that references these methods.Removing the Compliance App
Once the user profile data is stored elsewhere, the defunct database records for the user profile module can be deleted. Locate all of the Projects whose
is_account_project
field is true and delete all of the associated Task, TaskAnswer, and TaskAnswerHistory records, and the Project itself. Possibly equivalently, locate all AppVersion instances for the "account" compliance app in the AppSource whose "is_system_source" field is true, and delete any associated Tasks etc.Once this is done the
is_account_project
field will be defunct and can be removed in a migration. All AppVersion instances in the database that are for the user profile module can be deleted. Lastly, themodules/system/account
directory can be deleted.Other
See #632 for an example fix we had to do.
The text was updated successfully, but these errors were encountered: