Skip to content

Conversation

@ertgl
Copy link

@ertgl ertgl commented Oct 20, 2025

This PR relates to both #1738 and #2243, and includes the following works.

  1. Add bio field to accounts.Profile model.
  2. Fix a styling bug where the floating image causes a vertical space between words in the name, by its own height, on small screen sizes or for long names.
  3. Display Individual Members' names as links to their profile pages when associated to a user.
  4. Add admin action to send account invite mail to individual members.
    4.1. Create custom permission send_account_invite_mail on IndividualMember model.
    4.2. Add field account_invite_mail_sent_at to 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 Screenshot 2025-10-20 at 04 15 39
Image 2: Profile page (responsive) Screenshot 2025-10-20 at 04 18 58
Image 3: Profile edit form Screenshot 2025-10-20 at 04 15 29
Image 4: Vertical space between words caused by the floating image Screenshot 2025-10-20 at 04 08 11
Image 5: Links in the Individual Members list Screenshot 2025-10-20 at 04 30 34
Image 6: Links in the Former Individual Members list Screenshot 2025-10-20 at 04 31 22
Image 7: Optional user field on IndividualMember admin page Screenshot 2025-10-20 at 04 36 09
Image 8: Auto-completable user field on IndividualMember admin page Screenshot 2025-10-20 at 04 36 24
Image 9: Admin action to send account invite mail to individual members Screenshot 2025-10-21 at 05 14 07
Image 10: Messages to show the results after running the action Screenshot 2025-10-21 at 05 14 28

Additional Notes

  1. Currently, no maxlength specified for the bio field on the update form.
  2. We allow users to edit their names (user.profile.name), but in the Individual Members list, we display names from memberships (member.name).
  3. It is not apparent from the user's profile that they are an individual member (e.g., via a badge).

Fixes #1738 and fixes #2243

@ertgl
Copy link
Author

ertgl commented Oct 21, 2025

Next steps:

Additional screenshots:

Image 11: Account invite mail Screenshot 2025-10-21 at 05 20 46

@ertgl ertgl marked this pull request as ready for review October 21, 2025 03:19
Copy link
Contributor

@sarahboyce sarahboyce left a 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 }}
Copy link
Contributor

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

Copy link
Author

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.

Copy link
Author

@ertgl ertgl Oct 22, 2025

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

Copy link
Author

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:
Copy link
Contributor

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

Copy link
Author

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?

Copy link
Contributor

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 🤔

Copy link
Author

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?

Copy link
Contributor

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 👍

Copy link
Author

@ertgl ertgl Oct 23, 2025

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:

  1. Add trac_username field to Profile.
  2. Add ProfileAdmin class to allow overriding Trac username for a specific user (for retrieving stats).
  3. Add a utility function get_user_trac_username, to be used as a single source of truth.
  4. Refactor the profile view to use the function for retrieving the stats.
  5. Add test to verify that usernames can be overridden.
  6. Add another test to ensure trac_username field is not included by the publicly used ProfileForm.
  7. Add note about usernames to the email (but I didn't mention yet that it can be overridden when needed).

Additional screenshots:

Image 12: Profiles - admin page Screenshot 2025-10-23 at 09 11 04
Image 13: Update profile - admin page Screenshot 2025-10-23 at 09 11 22

Copy link
Author

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:

  1. If the user has a trac_username set, this indicates a verified username, so retrieve and render the stats for that specific trac_username.
  2. Otherwise, check if the user's username is used as trac_username by another user. If so, prevent rendering the stats.
  3. Otherwise, retrieve and render the stats for the user's username.
  4. 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(
Copy link
Contributor

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 🤔

Copy link
Author

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.

@ertgl
Copy link
Author

ertgl commented Oct 21, 2025

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.",
Copy link
Member

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:

  1. I love this PR, thanks so much for working on it! 💚
  2. When using ngettext, you should still be using %(count)d in the first argument (this is because some languages use the singular form for amounts other than 1):
Suggested change
"Sent account invite mail to 1 individual member.",
"Sent account invite mail to %(count)d individual member.",

Copy link
Author

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. 💚

Copy link
Author

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.

ertgl and others added 6 commits October 22, 2025 03:56
…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]>
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.

Add optional URLs for individual members Link IndividualMember to user profile page when available

3 participants