-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Link IndividualMember to user profile page #2277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…`AUTH_USER_MODEL`
…ciated with a user
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
|
Next steps:
Additional screenshots: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great start thank you @ertgl for picking this up!
I would add a few more tests and I have some initial comments 👍
|
|
||
| {% if user_obj.profile.bio %} | ||
| <p class="bio"> | ||
| {{ user_obj.profile.bio }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think given you wanted to add links it might be nice to use urlize here. I also think we should have a character limit on the bio, something like 3,000 characters 🤔
A different thought was whether we would let folks use markdown but maybe let's keep it simple
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that using urlize would be nice. So, both that this PR wouldn't get bigger and you can start collecting feedback from members sooner and decide later whether to support Markdown. If my contribution would be helpful, I'd be happy to implement it as well at any time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been done, but let's not mark it as resolved yet. I'll add tests for this.
Screen.Recording.2025-10-22.at.03.44.29.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I've added tests for this (hopefully everything is covered).
|
|
||
| We're updating the Django Individual Members list so each member's name can link to their djangoproject.com profile. On your profile, you can share a short bio, highlight your contributions to Django or the community, and provide ways for others to get in touch. | ||
|
|
||
| To have your name linked, please create an account (if you don't already have one) at: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it's worth mentioning that their account name should match their github username if they use their github account for Trac. This let's us show stats about their contributions in their profile page
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, thank you! That's something I wasn't aware of. I'll work on it. Additionally, I've checked the code and I'm thinking that we could provide another optional input to let user override the parameter passed to trac_stats.get_user_stats(username) function (also by displaying the username that overrides the user.username, on the page). Do you think these would be useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure as I guess folks could try to claim the stats of others as their own 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, displaying the username on the page wouldn't be enough. What if we put the input to the admin only instead, and mention in the email that if they have a mismatch they can request a fix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure that's an idea 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done the following:
- Add
trac_usernamefield toProfile. - Add
ProfileAdminclass to allow overriding Trac username for a specific user (for retrieving stats). - Add a utility function
get_user_trac_username, to be used as a single source of truth. - Refactor the profile view to use the function for retrieving the stats.
- Add test to verify that usernames can be overridden.
- Add another test to ensure
trac_usernamefield is not included by the publicly usedProfileForm. - Add note about usernames to the email (but I didn't mention yet that it can be overridden when needed).
Additional screenshots:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've refactored the profile view to prevent rendering false Trac stats in certain situations. Here's the step-by-step details:
- If the user has a
trac_usernameset, this indicates a verified username, so retrieve and render the stats for that specifictrac_username. - Otherwise, check if the user's username is used as
trac_usernameby another user. If so, prevent rendering the stats. - Otherwise, retrieve and render the stats for the user's username.
- All in a cached way.
Since Profile.trac_username field is not unique, this can also tolerate rare/temporal cases where multiple accounts belong to the same person and share the same trac_username.
Please feel free to let me know if anything should be handled differently.
| migrations.AddField( | ||
| model_name="individualmember", | ||
| name="user", | ||
| field=models.OneToOneField( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an idea, we could have a custom migration which links existing IndividualMember and User based off matching emails 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's done too. I also made it reusable to handle occasional stale states by adding a management command.
|
Thank you @sarahboyce! I appreciate your review and feedback. I'll add the additional tests and take your comments into account. |
members/admin.py
Outdated
| self.message_user( | ||
| request, | ||
| ngettext( | ||
| "Sent account invite mail to 1 individual member.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a quick drive-by comment to say that:
- I love this PR, thanks so much for working on it! 💚
- When using
ngettext, you should still be using%(count)din the first argument (this is because some languages use the singular form for amounts other than 1):
| "Sent account invite mail to 1 individual member.", | |
| "Sent account invite mail to %(count)d individual member.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're absolutely right! I missed that detail, and I'll fix it accordingly. Thanks so much for catching it and for the kind words. 💚
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK! I've fixed it.
…ails) 1. Implement `BoundFieldWithCharacterCounter` to add character counter specific data to any `CharField` inputs. 2. Implement character counter in JavaScript so we can enhance the page progressively. 3. Make `ProfileForm.bio` field use `BoundFieldWithCharacterCounter`. 4. Set maxlength for `ProfileForm.bio` field. 5. Render `profile.bio` with `urlize` to convert URLs and mail addresses in the plaintext into clickable links. Co-authored-by: Sarah Boyce <[email protected]>
for more information, see https://pre-commit.ci
…uages Co-authored-by: Baptiste Mispelon <[email protected]>
Co-authored-by: Sarah Boyce <[email protected]>
…ldWithCharacterCounter.get_characters_remaining_count` method
…nts race-conditions
for more information, see https://pre-commit.ci
… for details) - Add `accounts.Profile.trac_username` field. - Add `ProfileAdmin` to enable overriding Trac username for a specific user. - Refactor `user_profile` view to use `get_trac_username` function. Co-authored-by: Sarah Boyce <[email protected]>
for more information, see https://pre-commit.ci
…account_invite_mails_prevents_race_condition`
…t-invite mail's recipients
…ng_matches_client_side_js_implementation`
…another user in a verified way
…eck_if_user_username_is_used_as_trac_username_by_another_user`



This PR relates to both #1738 and #2243, and includes the following works.
biofield toaccounts.Profilemodel.4.1. Create custom permission
send_account_invite_mailonIndividualMembermodel.4.2. Add field
account_invite_mail_sent_atto prevent duplicated mails.4.3. Prevent potential race-conditions and duplications, using
select_for_update(nowait=False)and inner savepoints.4.4 Add filters to the admin page so users can see an overview of the current state.
Screenshots are included below.
Image 1: Profile page
Image 2: Profile page (responsive)
Image 3: Profile edit form
Image 4: Vertical space between words caused by the floating image
Image 5: Links in the Individual Members list
Image 6: Links in the Former Individual Members list
Image 7: Optional user field on IndividualMember admin page
Image 8: Auto-completable user field on IndividualMember admin page
Image 9: Admin action to send account invite mail to individual members
Image 10: Messages to show the results after running the action
Additional Notes
maxlengthspecified for thebiofield on the update form.user.profile.name), but in the Individual Members list, we display names from memberships (member.name).Fixes #1738 and fixes #2243