# update when User model changes
[docs]
def full_name(user):
"""
Derive a display name from a user's ``firstName`` and ``lastName`` fields.
Strips whitespace from each component before joining. Falls back to
``'Not provided'`` if both fields are blank or absent, ensuring the
return value is always a non-empty string suitable for display.
:param user: The user whose name is being formatted.
:type user: users.models.User
:returns: Full name string, or ``'Not provided'`` if both name fields
are empty.
:rtype: str
Example::
>>> full_name(user) # both fields set
'Jane Doe'
>>> full_name(empty_user) # both fields blank
'Not provided'
"""
first = (user.firstName or '').strip()
last = (user.lastName or '').strip()
return f"{first} {last}".strip() or 'Not provided'
[docs]
def serialize_user(user):
"""
Serialize a :class:`~users.models.User` instance into a standard API response dict.
Includes core identity, academic profile, background flags, and matching
state. Excludes sensitive fields such as ``password``, verification
tokens, and password reset tokens.
.. note::
If the :class:`~users.models.User` model fields change, update this
function and :func:`serialize_user_with_deletion` accordingly.
:param user: The user instance to serialize.
:type user: users.models.User
:returns: Dictionary of serialized user data safe for API responses.
:rtype: dict
**Response shape**::
{
"email": "jdoe@ucla.edu",
"firstName": "Jane",
"lastName": "Doe",
"role": "MENTEE",
"year": 2,
"major": ["Computer Science"],
"minor": [],
"hobbies": "chess, hiking",
"clubs": "ACM",
"goals": "Become a software engineer",
"international": false,
"commuter": false,
"firstgen": true,
"outofstate": false,
"transfer": false,
"otherBackground": "",
"isMatched": false,
"profilePictureUrl": "https://..."
}
"""
return {
"email": user.email,
"firstName": user.firstName,
"lastName": user.lastName,
"role": user.role,
"year": user.year,
"major": user.major,
"minor": user.minor,
"hobbies": user.hobbies,
"clubs": user.clubs,
"goals": user.goals,
"international": user.international,
"commuter": user.commuter,
"firstgen": user.firstgen,
"outofstate": user.outofstate,
"transfer": user.transfer,
"otherBackground": user.otherBackground,
"isMatched": user.isMatched,
"profilePictureUrl": user.profilePictureUrl,
}
[docs]
def serialize_user_with_deletion(user):
"""
Serialize a :class:`~users.models.User` instance including soft-deletion metadata.
Extends :func:`serialize_user` with ``is_deleted`` and
``permanent_deletion_date``, intended for responses where the client
needs to display a deletion warning or countdown — for example, the
login response when an account is within its grace period.
``permanent_deletion_date`` is serialized as an ISO 8601 string when
present, or ``null`` if the date has not been set.
:param user: The soft-deleted (or deletion-pending) user instance to serialize.
:type user: users.models.User
:returns: Dictionary of serialized user data including deletion fields.
:rtype: dict
**Additional fields beyond** :func:`serialize_user`::
{
"is_deleted": true,
"permanent_deletion_date": "2024-01-15T10:30:00+00:00"
}
Example::
>>> serialize_user_with_deletion(pending_user)
{
"email": "jdoe@ucla.edu",
...,
"is_deleted": True,
"permanent_deletion_date": "2024-01-15T10:30:00+00:00"
}
"""
return {
**serialize_user(user),
'is_deleted': user.is_deleted,
'permanent_deletion_date': (
user.permanent_deletion_date.isoformat()
if user.permanent_deletion_date else None
),
}