matching package
Subpackages
Submodules
matching.admin module
matching.apps module
- class matching.apps.MatchingConfig(app_name, app_module)[source]
Bases:
AppConfig- default_auto_field = 'django_mongodb_backend.fields.ObjectIdAutoField'
- name = 'matching'
- ready()[source]
Import signals when app loads. Note: Added noqa so linter won’t remove the function. https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready https://stackoverflow.com/questions/58362534/i-m-confused-about-the-ready-function-used-inside-app-py
matching.models module
- class matching.models.Score(*args, **kwargs)[source]
Bases:
ModelStores the computed compatibility score between a mentee and a mentor.
Each row represents a unique mentee–mentor pairing. Scores are used by the matching algorithm to rank and assign mentors to mentees. The
(mentee_email, mentor_email)pair is enforced as unique at the database level.- mentee_email
Email address of the mentee in the pairing.
- Type:
EmailField
- mentor_email
Email address of the mentor in the pairing.
- Type:
EmailField
- score
Computed compatibility score for this pairing.
- Type:
FloatField
- created_at
Timestamp when the score was first calculated.
- Type:
DateTimeField
- updated_at
Timestamp of the most recent score update.
- Type:
DateTimeField
- mentee_email
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- mentor_email
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- score
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- created_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- updated_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- property mentee
Retrieve the
Userinstance for the mentee.Performs a live database lookup by
mentee_emailon every access.- Returns:
The
Userrecord whose email matchesmentee_email.- Return type:
users.models.User
- Raises:
users.models.User.DoesNotExist – If no user with
mentee_emailexists in the database.
Example:
>>> score.mentee.firstName 'Jane'
- property mentor
Retrieve the
Userinstance for the mentor.Performs a live database lookup by
mentor_emailon every access.- Returns:
The
Userrecord whose email matchesmentor_email.- Return type:
users.models.User
- Raises:
users.models.User.DoesNotExist – If no user with
mentor_emailexists in the database.
Example:
>>> score.mentor.firstName 'John'
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- exception NotUpdated
Bases:
ObjectNotUpdated,DatabaseError
- get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)
- get_next_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=True, **kwargs)
- get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)
- get_previous_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=False, **kwargs)
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>
matching.scoring module
- matching.scoring.get_embedding_model()[source]
Return the shared
SentenceTransformerinstance, loading it on first call.Uses a module-level singleton (
_embedding_model) to avoid reloading the'all-MiniLM-L6-v2'model on every scoring request. The model is approximately 80 MB and takes several seconds to initialise, so lazy loading defers that cost until the first actual score calculation rather than at import time.- Returns:
The loaded
SentenceTransformermodel instance.- Return type:
sentence_transformers.SentenceTransformer
- matching.scoring.build_profile_text(user)[source]
Concatenate a user’s semantic profile fields into a single text block.
Combining all fields into one string before encoding gives the embedding model full context and produces richer, more discriminative embeddings than encoding each field in isolation. Fields that are empty or falsy are omitted entirely so they do not dilute the representation.
- Parameters:
user (users.models.User) – The user whose profile fields are being combined.
- Returns:
A newline-separated string of labelled profile fields, or an empty string if all fields are blank.
- Return type:
Example:
>>> build_profile_text(user) 'Major: Computer Science\nHobbies and interests: chess, hiking\nGoals: SWE internship'
- matching.scoring.calculate_match_score(mentee, mentor)[source]
Compute a compatibility score between a mentee and a mentor.
Combines three weighted sub-scores:
Profile text similarity (up to 70 points) — cosine similarity of sentence embeddings built from
build_profile_text(), scaled to the 0–70 range.Year compatibility (up to 10 points) — gap-based scoring from
calculate_year_compatibility().Special category overlap (up to 20 points) — 5 points per shared background category (
international,commuter,firstgen,outofstate,transfer), capped at 20.
- Parameters:
mentee (users.models.User) – The mentee side of the pairing.
mentor (users.models.User) – The mentor side of the pairing.
- Returns:
Total compatibility score rounded to two decimal places, in the range
[0.0, 100.0].- Return type:
Example:
>>> calculate_match_score(mentee_user, mentor_user) 73.45
- matching.scoring.calculate_year_compatibility(mentee_year, mentor_year)[source]
Score the academic-year gap between a mentee and a mentor.
Rewards pairings where the mentor is 2–3 years ahead of the mentee, reflecting the expectation that a slightly senior mentor provides the most relevant guidance. Both year values are normalized via
_parse_year()before comparison; a value of0(unparseable or missing) causes the function to return a neutral mid-range score of5.0.Scoring table:
Condition
Points
Year 1 mentee / Year 3
10.0
Year 1 mentee / Year 4
9.0
Gap ≥ 3 years
9.0
Gap = 2 years
8.0
Gap = 1 year
6.0
Same year (gap = 0)
3.0
Mentor is junior
1.0
Either year unknown
5.0
- Parameters:
- Returns:
Year-compatibility sub-score in the range
[1.0, 10.0].- Return type:
Example:
>>> calculate_year_compatibility(1, 3) 10.0 >>> calculate_year_compatibility(2, 2) 3.0
matching.serializers module
- matching.serializers.SPECIAL_CATEGORY_FIELDS = {'commuter': 'commuter', 'firstgen': 'firstgen', 'international': 'international', 'outofstate': 'outofstate', 'transfer': 'transfer'}
Maps
Userboolean background fields to the label returned in API responses underspecialCategories. Add, remove, or rename entries here to control which flags are exposed and how they are labelled without touching serializer logic.
- matching.serializers.MAX_MENTEES = 2
Maximum number of mentees a single mentor may be assigned. Mirrors
users.models.MAX_MENTEESand is re-exported here so that matching serializers and services can import from a single location.
- matching.serializers.serialize_mentor(mentor, score=None)[source]
Serialize a mentor
Userinstance into an API-ready dictionary.Includes profile fields, available roster capacity, and an optional compatibility
score. Thescorefield is included in the output only when explicitly supplied, keeping the schema consistent between match-listing responses (which need a score) and plain profile lookups (which do not).- Parameters:
mentor (users.models.User) – The mentor user instance to serialize.
score (float or None) – Compatibility score for this mentor relative to a specific mentee. Pass
None(default) to omit the field from the response.
- Returns:
Dictionary of serialized mentor data. When
scoreis provided the dict includes a'score'key; otherwise it is absent.- Return type:
Example — match listing (with score):
>>> serialize_mentor(mentor_user, score=0.87) { 'email': 'mentor@ucla.edu', 'name': 'John Smith', 'score': 0.87, 'available_slots': 1, ... }
Example — profile lookup (without score):
>>> serialize_mentor(mentor_user) { 'email': 'mentor@ucla.edu', 'name': 'John Smith', 'available_slots': 2, ... }
- matching.serializers.serialize_mentee(mentee)[source]
Serialize a mentee
Userinstance into an API-ready dictionary.Returns core profile fields and background category labels. Does not include matching metadata such as
isMatchedormatchedMentorEmail— those are considered internal state and are not exposed through this serializer.- Parameters:
mentee (users.models.User) – The mentee user instance to serialize.
- Returns:
Dictionary of serialized mentee data.
- Return type:
Example:
>>> serialize_mentee(mentee_user) { 'email': 'mentee@g.ucla.edu', 'name': 'Jane Doe', 'major': ['Biology'], 'minor': [], 'year': 1, 'hobbies': 'hiking', 'clubs': 'Pre-Med Society', 'goals': 'Become a doctor', 'specialCategories': ['firstgen', 'transfer'] }
- matching.serializers.full_name(user)[source]
Derive a display name from a user’s
firstNameandlastNamefields.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.- Parameters:
user (users.models.User) – The user whose name is being formatted.
- Returns:
Full name string, or
'Not provided'if both name fields are empty.- Return type:
Example:
>>> full_name(user) # both fields set 'Jane Doe' >>> full_name(empty_user) # both fields blank 'Not provided'
- matching.serializers.special_categories(user)[source]
Return a list of background category labels that apply to the given user.
Iterates over
SPECIAL_CATEGORY_FIELDSand includes the label for each field whose value is truthy on the user instance. Fields absent from the user object are treated asFalseviagetattrdefault.To add or remove a category from API responses, update
SPECIAL_CATEGORY_FIELDS— no changes to this function are needed.- Parameters:
user (users.models.User) – The user whose background flags are being evaluated.
- Returns:
List of label strings for all truthy background fields. Returns an empty list if no flags are set.
- Return type:
Example:
>>> special_categories(user) # firstgen and transfer flags set ['firstgen', 'transfer'] >>> special_categories(user) # no flags set []
matching.services module
- exception matching.services.MatchingError(message, status=400)[source]
Bases:
ExceptionBase exception for all matching-layer errors.
Carries an HTTP
statuscode alongside the message so that views can return the appropriate response status without additional branching logic.- Parameters:
Example:
raise MatchingError('Something went wrong', status=400)
- exception matching.services.NotFound(message)[source]
Bases:
MatchingErrorRaised when a required resource (user, mentor, mentee) cannot be found.
Specialization of
MatchingErrorthat always setsstatus=404.- Parameters:
message (str) – Human-readable description of the missing resource.
Example:
raise NotFound('Mentor not found')
- exception matching.services.Conflict(message)[source]
Bases:
MatchingErrorRaised when a matching operation conflicts with the current system state.
Specialization of
MatchingErrorthat always setsstatus=409. Typical use case: attempting to add a mentee to a mentor who is already at full capacity.- Parameters:
message (str) – Human-readable description of the conflict.
Example:
raise Conflict('This mentor already has two mentees.')
- exception matching.services.Forbidden(message)[source]
Bases:
MatchingErrorRaised when a user attempts an action they are not authorized to perform.
Specialization of
MatchingErrorthat always setsstatus=403.- Parameters:
message (str) – Human-readable description of the authorization failure.
Example:
raise Forbidden('You do not have permission to perform this action.')
- matching.services.get_ranked_matches(mentee)[source]
Return a ranked list of compatible mentors for the given mentee.
Queries all
Scorerows for the mentee, resolves each to aUser, and filters out:Mentors on the mentee’s
blacklisted_mentorslist.Mentors whose
current_menteesroster is already at capacity (>= MAX_MENTEES).Score rows whose
mentor_emailno longer corresponds to an existing user (silently skipped).
The remaining mentors are sorted primary by score descending, secondary by
date_joinedascending as a tiebreaker (earlier joiners are preferred).- Parameters:
mentee (users.models.User) – The mentee user for whom matches are being retrieved.
- Returns:
List of serialized mentor dicts, each including a
scorefield, ordered from best to worst match.- Return type:
Example:
>>> matches = get_ranked_matches(mentee_user) >>> matches[0]['score'] 0.92
- matching.services.select_mentor(mentee, mentor_email)[source]
Match a mentee with their chosen mentor.
Validates that the mentee is not already matched, that the target user exists and holds the
MENTORrole, and that the mentor’s roster is not full. On success, updatesisMatchedandmatchedMentorEmailon the mentee and appends the mentee’s email to the mentor’scurrent_mentees.- Parameters:
mentee (users.models.User) – The mentee initiating the match request.
mentor_email (str) – Email address of the mentor to match with.
- Returns:
The mentor
Userinstance after the match is recorded.- Return type:
users.models.User
- Raises:
MatchingError – If the mentee is already matched (HTTP 400), or if the resolved user is not a mentor (HTTP 400).
NotFound – If no user exists for
mentor_email(HTTP 404).Conflict – If the mentor’s roster is already at capacity (HTTP 409).
Example:
>>> mentor = select_mentor(mentee_user, 'mentor@ucla.edu')
- matching.services.mentee_unmatch(mentee, mentor_email)[source]
Remove the match between a mentee and their current mentor.
Performs the following operations in order:
Verifies the mentor exists and is the mentee’s current match.
Clears
isMatchedandmatchedMentorEmailon the mentee.Removes the mentee from the mentor’s
current_menteesroster.Blacklists the mentor on the mentee’s account via
blacklist_mentor()to prevent re-matching.Hard-deletes all chat messages between the pair via
_delete_messages_between().
- Parameters:
mentee (users.models.User) – The mentee requesting the unmatch.
mentor_email (str) – Email address of the mentor to unmatch from.
- Raises:
MatchingError – If the mentee is not currently matched with the specified mentor (HTTP 400).
NotFound – If no user exists for
mentor_email(HTTP 404).
Example:
>>> mentee_unmatch(mentee_user, 'mentor@ucla.edu')
- matching.services.mentor_unmatch(mentor, mentee_email)[source]
Remove a specific mentee from a mentor’s active roster.
Performs the following operations in order:
Verifies the mentee exists and is on the mentor’s current roster.
Delegates roster cleanup to
remove_mentee(), which handles the database update and in-memory refresh internally.Clears
isMatchedandmatchedMentorEmailon the mentee.Blacklists the mentor on the mentee’s account via
blacklist_mentor()to prevent re-matching.Hard-deletes all chat messages between the pair via
_delete_messages_between().
- Parameters:
mentor (users.models.User) – The mentor initiating the unmatch.
mentee_email (str) – Email address of the mentee to remove.
- Raises:
MatchingError – If the specified mentee is not on the mentor’s current roster (HTTP 400).
NotFound – If no user exists for
mentee_email(HTTP 404).
Example:
>>> mentor_unmatch(mentor_user, 'mentee@g.ucla.edu')
matching.signals module
- matching.signals.calculate_and_store_scores_for_user(user)[source]
- matching.signals.recalculate_scores_for_user(user)[source]
- matching.signals.handle_user_profile_completion(sender, instance, created, **kwargs)[source]
matching.test_scoring module
- matching.test_scoring.make_user(hobbies='', goals='', clubs='', major=None, minor=None, year='1', international=False, commuter=False, firstgen=False, outofstate=False, transfer=False)[source]
- class matching.test_scoring.TestYearCompatibility(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_optimal_pairing_1st_3rd()[source]
- test_strong_pairing_1st_4th()[source]
- test_large_gap_pairing()[source]
- test_two_year_gap()[source]
- test_one_year_gap()[source]
- test_same_year()[source]
- test_negative_gap()[source]
- test_5_plus_year_parsing()[source]
- test_missing_year_data()[source]
- test_invalid_year_strings()[source]
- class matching.test_scoring.TestMatchScoring(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_high_similarity_cs_match()[source]
- test_cross_discipline_mismatch()[source]
- test_same_field_different_focus()[source]
- test_interdisciplinary_match()[source]
- test_special_category_boost()[source]
- test_identical_profiles()[source]
- test_missing_data_handling()[source]
- test_empty_strings_handling()[source]
- test_score_range_validation()[source]
- test_generic_vs_specific()[source]
- class matching.test_scoring.TestEdgeCases(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_year_boundary_values()[source]
- test_build_profile_text_empty()[source]
- test_build_profile_text_full()[source]
- test_single_word_vs_paragraph()[source]
- test_similar_meaning_different_words()[source]
- test_completely_unrelated_profiles()[source]
- test_unicode_and_special_characters()[source]
matching.test_scoring_advanced module
Advanced real-world integration tests for the combined-text scoring algorithm.
- class matching.test_scoring_advanced.Profile(hobbies='', goals='', clubs='', major=None, minor=None, year='1', international=False, commuter=False, firstgen=False, outofstate=False, transfer=False)[source]
Bases:
objectProfile object matching the current User schema.
- class matching.test_scoring_advanced.TestRealWorldScenarios(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_cs_freshman_seeking_startup_mentor()[source]
- test_pre_med_mentorship()[source]
- test_engineering_to_consulting_mismatch()[source]
- test_international_student_pairing()[source]
- test_women_in_stem_mentorship()[source]
- test_career_switcher_scenario()[source]
- test_graduate_school_prep()[source]
- class matching.test_scoring_advanced.TestFieldSpecificScenarios(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_frontend_vs_backend_developer()[source]
- test_theoretical_vs_applied_math()[source]
- test_creative_writing_vs_journalism()[source]
- class matching.test_scoring_advanced.TestEdgeCaseProfiles(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_very_brief_vs_detailed_profiles()[source]
- test_interdisciplinary_double_major()[source]
- test_all_generic_interests()[source]
- test_special_category_max_cap()[source]
4 shared categories should add exactly 20 points.
- test_minor_field_included_in_profile_text()[source]
Minor should appear in the combined profile text.
matching.tests module
- class matching.tests.MatchingAPITests(methodName='runTest')[source]
Bases:
TestCase- setUp()[source]
Hook method for setting up the test fixture before exercising it.
- test_get_mentor_matches_ranked()[source]
Ensures mentee receives mentors sorted by high score first
- test_select_mentor_success()[source]
Ensures a mentee can successfully match with a mentor
- test_mentor_capacity_limit()[source]
Ensures a mentor with 2 mentees is rejected
- test_unauthorized_role_blocked()[source]
Ensures a mentor cannot access mentee-only matching endpoints
- test_incomplete_profile_no_matches()[source]
Ensures users without major/year see 0 matches
- test_unmatch_lifecycle()[source]
Verifies unmatching clears state and blacklists the mentor
- test_deleted_user_cannot_match()[source]
Ensures users pending deletion are blocked from matching
- test_rematch_endpoint_logic()[source]
Verifies the rematch endpoint returns the same ranked data
matching.urls module
matching.utils module
- matching.utils.get_top_matches_for_mentee(mentee, limit=10)[source]
Return the highest-scoring
Scorerows for a mentee.Results are ordered by
scoredescending and sliced tolimitrows. No filtering for blacklisted or full mentors is applied here — this is a raw score lookup intended for administrative or diagnostic use. For the filtered, serialized match list used in the matching UI, seematching.services.get_ranked_matches().- Parameters:
mentee (users.models.User) – The mentee whose scores are being queried.
limit (int) – Maximum number of score rows to return. Defaults to
10.
- Returns:
Queryset of
Scoreinstances ordered by score descending, sliced tolimit.- Return type:
django.db.models.QuerySet
Example:
>>> get_top_matches_for_mentee(mentee_user, limit=5) <QuerySet [<Score: mentee@g.ucla.edu - mentor@ucla.edu: 0.91>, ...]>
- matching.utils.get_top_matches_for_mentor(mentor, limit=10)[source]
Return the highest-scoring
Scorerows for a mentor.Results are ordered by
scoredescending and sliced tolimitrows. Intended for administrative or diagnostic use; does not apply blacklist or capacity filtering.- Parameters:
mentor (users.models.User) – The mentor whose scores are being queried.
limit (int) – Maximum number of score rows to return. Defaults to
10.
- Returns:
Queryset of
Scoreinstances ordered by score descending, sliced tolimit.- Return type:
django.db.models.QuerySet
Example:
>>> get_top_matches_for_mentor(mentor_user, limit=5) <QuerySet [<Score: mentee@g.ucla.edu - mentor@ucla.edu: 0.91>, ...]>
- matching.utils.recalculate_all_scores()[source]
Rebuild the entire
Scoretable from scratch.Deletes all existing score rows, then computes a fresh
calculate_match_score()for every eligible mentee–mentor pair and bulk-inserts the results in batches of 1 000 within a single database transaction.Users on either side who do not pass
_has_enough_profile_data()are excluded from the calculation entirely.Warning
This function performs a full table wipe before re-inserting. It is intended for scheduled background jobs or admin-triggered resets, not for request-cycle use. For incremental updates triggered by a profile change, use
recalculate_scores_for_mentee()instead.- Returns:
None. Prints the number of score records created to stdout.
Example:
>>> recalculate_all_scores() Created 240 score records
- matching.utils.UNMATCH_CONFIRMATION = 'I would like to unmatch'
Exact confirmation string a user must submit to complete an unmatch request. Referenced by
require_confirmation()and surfaced in error messages so the frontend can display the expected phrase to the user.
- matching.utils.require_auth(request)[source]
Guard helper that rejects unauthenticated requests.
Intended to be called at the top of matching views using the walrus operator pattern:
if err := require_auth(request): return err
- Parameters:
request (django.http.HttpRequest) – The incoming HTTP request.
- Returns:
A
JsonResponsewith HTTP 401 if the user is not authenticated, orNoneif the check passes.- Return type:
django.http.JsonResponse or None
- matching.utils.require_role(request, role)[source]
Guard helper that rejects requests from users who do not hold a specific role.
Intended to be called at the top of matching views using the walrus operator pattern:
if err := require_role(request, 'MENTEE'): return err
- Parameters:
request (django.http.HttpRequest) – The incoming HTTP request.
role (str) – The required role string, e.g.
'MENTEE'or'MENTOR'.
- Returns:
A
JsonResponsewith HTTP 403 if the user’s role does not match, orNoneif the check passes.- Return type:
django.http.JsonResponse or None
- matching.utils.require_confirmation(data, expected='I would like to unmatch')[source]
Guard helper that validates a user-supplied confirmation string.
Prevents destructive unmatch operations from being triggered accidentally by requiring the caller to echo back the exact phrase defined in
UNMATCH_CONFIRMATION. The comparison is performed after stripping leading and trailing whitespace.Intended to be called in views using the walrus operator pattern:
if err := require_confirmation(data): return err
- Parameters:
- Returns:
A
JsonResponsewith HTTP 400 and an instructional error message if the confirmation does not match, orNoneif it passes.- Return type:
django.http.JsonResponse or None
- matching.utils.recalculate_scores_for_mentee(mentee)[source]
Incrementally refresh compatibility scores between one mentee and all eligible mentors.
Uses
update_or_createto upsert aScorerow for every mentor who passes_has_enough_profile_data(), preserving scores for existing pairs while creating rows for any new mentors. If the mentee themselves does not have enough profile data the function returns immediately without writing anything.Intended to be called after a mentee updates their profile so that the match dashboard reflects their latest information without requiring a full table rebuild. For a complete reset of all scores, use
recalculate_all_scores()instead.- Parameters:
mentee (users.models.User) – The mentee whose scores should be refreshed.
- Returns:
None. Returns early without side effects if the mentee’s profile is incomplete.
Example:
>>> recalculate_scores_for_mentee(mentee_user)
- matching.utils.require_not_deleted(request)[source]
Guard helper that rejects requests from accounts pending deletion.
Prevents soft-deleted users from accessing matching features while their account is in the grace period. Intended to be called at the top of matching views using the walrus operator pattern:
if err := require_not_deleted(request): return err
- Parameters:
request (django.http.HttpRequest) – The incoming HTTP request.
- Returns:
A
JsonResponsewith HTTP 403 and a cancellation prompt if the account is soft-deleted, orNoneif the check passes.- Return type:
django.http.JsonResponse or None
matching.views module
- matching.views.get_mentor_matches(request)[source]
Return a ranked list of compatible mentors for the authenticated mentee.
Delegates to
services.get_ranked_matches()to compute and sort mentor candidates based on pre-calculated compatibility scores.- Parameters:
request (django.http.HttpRequest) – The incoming HTTP GET request. Must belong to an authenticated, non-deleted user with the
MENTEErole.- Returns:
HTTP 200 with
matches(list of serialized mentor objects) andtotal(count) on success.HTTP 401 if the request is unauthenticated.
HTTP 403 if the user does not have the
MENTEErole.HTTP 404 if the account is pending deletion.
- Return type:
Success response (HTTP 200):
{ "matches": [ { ...mentor fields... }, ... ], "total": 5 }
- matching.views.rematch(request)[source]
Re-fetch the ranked mentor list for the authenticated mentee.
Thin wrapper around
get_mentor_matches()kept as a distinct endpoint for semantic clarity in the URL configuration (e.g./matching/rematch/vs/matching/matches/).- Parameters:
request (django.http.HttpRequest) – The incoming HTTP GET request. Must belong to an authenticated, non-deleted user with the
MENTEErole.- Returns:
Identical response to
get_mentor_matches().- Return type:
- matching.views.select_mentor(request)[source]
Match the authenticated mentee with a chosen mentor.
Delegates to
services.select_mentor(), which validates capacity, blacklist rules, and existing match state before creating the pairing.- Parameters:
request (django.http.HttpRequest) – The incoming HTTP POST request containing a JSON body with
mentor_email. Must belong to an authenticated, non-deleted user with theMENTEErole.- Returns:
HTTP 200 with
success,message, and serializedmentordata on success.HTTP 400 if the request body is invalid JSON or
mentor_emailis absent.HTTP 401 if the request is unauthenticated.
HTTP 403 if the user does not have the
MENTEErole.HTTP 404 if the account is pending deletion.
Appropriate error status from
MatchingErrorif the pairing is not permitted.
- Return type:
- Raises:
MatchingError – Caught internally; returns the error message and its associated HTTP status code.
Request body (JSON):
{ "mentor_email": "mentor@ucla.edu" }
Success response (HTTP 200):
{ "success": true, "message": "Successfully matched with mentor", "mentor": { ...mentor fields... } }
- matching.views.get_my_mentor(request)[source]
Return the mentor currently matched to the authenticated mentee.
Reads
matchedMentorEmailfrom the session user and fetches the correspondingUserrecord via the internal service helper.- Parameters:
request (django.http.HttpRequest) – The incoming HTTP GET request. Must belong to an authenticated, non-deleted user with the
MENTEErole who is currently matched.- Returns:
HTTP 200 with a serialized
mentorobject on success.HTTP 400 if
isMatchedisFalse.HTTP 401 if the request is unauthenticated.
HTTP 403 if the user does not have the
MENTEErole.HTTP 404 if
matchedMentorEmailis absent or the mentor record no longer exists.
- Return type:
- Raises:
MatchingError – Caught internally; returns the error message and its associated HTTP status code.
Success response (HTTP 200):
{ "mentor": { ...mentor fields... } }
- matching.views.get_my_mentees(request)[source]
Return all mentees currently assigned to the authenticated mentor.
Iterates over
current_menteeson the session user, fetches eachUserrecord, and silently skips any email addresses that no longer correspond to an existing account.- Parameters:
request (django.http.HttpRequest) – The incoming HTTP GET request. Must belong to an authenticated, non-deleted user with the
MENTORrole.- Returns:
HTTP 200 with
mentees(list of serialized mentee objects) andtotal(count) on success. The list may be empty if the mentor has no current mentees.HTTP 401 if the request is unauthenticated.
HTTP 403 if the user does not have the
MENTORrole.HTTP 404 if the account is pending deletion.
- Return type:
Success response (HTTP 200):
{ "mentees": [ { ...mentee fields... }, ... ], "total": 2 }
- matching.views.unmatch(request)[source]
Remove an existing match between the authenticated user and a counterpart.
Behaviour differs by role:
MENTEE — requires
mentor_emailin the body; delegates toservices.mentee_unmatch().MENTOR — requires
mentee_emailin the body; delegates toservices.mentor_unmatch().
A confirmation string must be present in the request body (validated by
require_confirmation()) before any unmatching logic is executed.- Parameters:
request (django.http.HttpRequest) – The incoming HTTP POST request containing a JSON body with a confirmation field and either
mentor_emailormentee_emaildepending on the caller’s role. Must belong to an authenticated, non-deleted user.- Returns:
HTTP 200 with
'Successfully unmatched'on success.HTTP 400 if the request body is invalid JSON, the required email field is absent, or the confirmation check fails.
HTTP 401 if the request is unauthenticated.
HTTP 403 if the user’s role is neither
MENTEEnorMENTOR.HTTP 404 if the account is pending deletion.
Appropriate error status from
MatchingErrorif the unmatch operation is not permitted.
- Return type:
- Raises:
MatchingError – Caught internally; returns the error message and its associated HTTP status code.
Request body — mentee caller (JSON):
{ "confirmation": "unmatch", "mentor_email": "mentor@ucla.edu" }
Request body — mentor caller (JSON):
{ "confirmation": "unmatch", "mentee_email": "mentee@g.ucla.edu" }
- matching.views.update_profile(request)[source]
Update the authenticated user’s profile and refresh match scores if applicable.
Applies the supplied field updates via
User.update_profile(). If the caller is aMENTEE, compatibility scores against all available mentors are immediately recalculated viarecalculate_scores_for_mentee()so that the match dashboard reflects the latest profile state.- Parameters:
request (django.http.HttpRequest) – The incoming HTTP PUT request containing a JSON body with one or more profile field key-value pairs. Must belong to an authenticated user.
- Returns:
HTTP 200 with a success message on update.
HTTP 400 if the request body is not valid JSON.
HTTP 401 if the request is unauthenticated.
- Return type:
Request body (JSON):
{ "firstName": "Jane", "year": 3, "hobbies": "hiking, chess" }
Module contents
- show-inheritance:
- undoc-members: