Skip to content

Add the Profile model and SkillProfile models - #828

Open
AdrianDAlessandro wants to merge 6 commits into
mainfrom
profile-model
Open

AdrianDAlessandro wants to merge 6 commits into
mainfrom
profile-model

Conversation

@AdrianDAlessandro

Copy link
Copy Markdown
Collaborator

Description

Apologies for the long PR! These new models are in a part of the DB that touches a lot of the code, but this is part of the motivation for this change. Hopefully, this will make future changes related to skill profiles simpler.

This adds a Profile model that is to be used for two things:

  • Linking users to a skills profile (instead of directly linking users to UserSkills, as was done before)
  • Enable creating "career profiles" (i.e. skills profiles that are not linked to any user)

All users must have a Profile, this is ensured by a post-save signal that is fired whenever a new user is created. There is also a migration that creates a profile for every existing user.

It also replaces the previous UserSkill model with a SkillProfile model. This is implemented in a way that ensures all existing users' skill profiles remain intact. There is a series of migrations for this.

All the views, forms and templates that interact with the skill profiles have been changed as minimally as possible, focussing on:

  • Renaming "User Skill" to "Skill Profile" in every instance (i.e. user_skill becomes skill_profile, etc)
  • Only passing the user.profile object when it is all that is needed (i.e. SkillProfileForm methods no longer take user as an input)

Fixes #824

Type of change

  • Documentation (non-breaking change that adds or improves the documentation)
  • New feature (non-breaking change which adds functionality)
  • Optimization (non-breaking, back-end change that speeds up the code)
  • Technical work (non-breaking, change which is work as part of a new feature)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (whatever its nature)

Key checklist

  • All tests pass (eg. python -m pytest)
  • The documentation builds and looks OK (eg. mkdocs serve)
  • Pre-commit hooks run successfully (eg. pre-commit run --all-files)

Further checks

  • Code is commented, particularly in hard-to-understand areas
  • Tests added or an issue has been opened to tackle that in the future. (Indicate issue here: # (issue))

@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.88525% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ain/migrations/0033_populate_userskill_profiles.py 62.50% 9 Missing ⚠️
main/admin.py 88.57% 4 Missing ⚠️
main/forms.py 80.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Admin deletion and migration rollback can lose assessment ownership, and existing shared links no longer render correctly.

3 open issues
What changed in this PR

This PR decouples skill assessments from authentication accounts by introducing Profile and replacing UserSkill with SkillProfile, supporting standalone career profiles alongside user profiles.

Changes:

  • Add profile models, automatic creation for new users, and migrations for existing assessments.
  • Update forms, views, admin pages, charts, and exports to use skill profiles.
  • Adapt tests, sample data, and developer documentation.
File Description
tests/​main/​test_user_models.py Test profile creation, ownership, uniqueness, and deletion.
tests/​main/​test_registration_views.py Verify registration creates a profile.
tests/​main/​test_main_views.py Update view assertions and chart payloads.
tests/​main/​test_admin_views.py Replace proxy-admin tests with profile-admin tests.
tests/​main/​test_account_data_views.py Update download tests and JSON keys.
tests/​main/​conftest.py Replace the assessment fixture with SkillProfile.
tests/​data/​example_role.json Rename the sample chart-data key.
main/​views/​account_views.py Use profile-backed assessments and forms.
main/​views/​account_data_views.py Export assessments through profiles.
main/​urls.py Reference renamed download views.
main/​templates/​main/​snippets/​skill-wheel.html Read the renamed chart-data key.
main/​templates/​main/​snippets/​share_skill_profile_dropdown.html Update the sharing-template include.
main/​templates/​main/​snippets/​export_skill_profile.html Update export payload access and usage comment.
main/​templates/​main/​snippets/​create_skill_profile_link.html Correct the template usage comment.
main/​static/​assets/​sample_data/​sample_profile_59.json Update the sample profile payload key.
main/​static/​assets/​sample_data/​sample_profile_41.json Update the sample profile payload key.
main/​static/​assets/​sample_data/​sample_profile_1.json Update the sample profile payload key.
main/​signals.py Create profiles when users are created.
main/​models/​user_models.py Introduce profiles and profile-owned assessments.
main/​migrations/​0035_rename_userskill_skillprofile.py Rename the assessment model.
main/​migrations/​0034_delete_userproxy_remove_userskill_unique_user_skill_and_more.py Finalize profile ownership and constraints.
main/​migrations/​0033_populate_userskill_profiles.py Create existing users’ profiles and transfer assessments.
main/​migrations/​0032_alter_userskill_user_profile_userskill_profile.py Introduce the transitional profile schema.
main/​forms.py Accept profiles when editing assessments.
main/​apps.py Register profile-creation signals.
main/​admin.py Replace the user proxy with profile administration.
docs/​dev-guide/​development.md Document cleanup of generated documentation.
docs/​dev-guide/​architecture.md Describe profile ownership and automatic creation.

Review effort: Balanced

Comment thread main/admin.py Resolved

@TinyMarsh TinyMarsh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have one potential issue. The rest of the PR looks good though!

Comment thread main/admin.py
Comment on lines +242 to +243
if obj is None:
return True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be an issue with this. But I might be completely wrong 😅

So this is here so that the bulk deletion checkboxes appear, that's fine. But, the problem is that Django’s built-in Delete selected profiles action then deletes the selected profiles and I'm not sure it repeats this custom permission check separately for each profile. So a user with the relevant delete permissions can select a user-linked profile and delete it in bulk, even though deleting that same profile from its individual profile page is blocked.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure of the exact order of things, but this is what I landed on when trying multiple options. It does appear that this function is called multiple times, at multiple stages, both with and without obj defined. When trying to delete a user-linked profile with the bulk-delete facility, you get a page saying you don't have permission:

Screenshot 2026-11-02 at 14 05 45

But it remains possible to delete profiles with no associated user.

@TinyMarsh TinyMarsh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After addressing the delete permission query, this now looks good.

@AdrianDAlessandro
AdrianDAlessandro marked this pull request as draft November 4, 2026 16:55
@AdrianDAlessandro
AdrianDAlessandro marked this pull request as ready for review November 4, 2026 16:55

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a Profile model to decouple framework profiles from users

4 participants