Feature: User Profile Management
Relevant source files
The following files were used as context for generating this wiki page:The User Profile Management feature, encapsulated within the profiles app, extends Django's built-in User model to store additional information and preferences for each user. Its primary purpose is to manage personal details, contact information, preferences like newsletter subscriptions, and a crucial distinction between 'Buyer' and 'Seller' account types. This system provides a personalized experience, allowing users to view and edit their data and switch their account roles, which directly impacts their capabilities within the Becathlon application, such as the ability to list products.
This module is central to user-specific functionality, linking authentication with application-level roles and preferences. It includes data models, forms for data manipulation, views to handle user requests, and templates for the user interface.
Data Model
The core of the profile system is the Profile model, which maintains a one-to-one relationship with Django's User model. A Profile instance is automatically created for each new User via a signal handler.
Sources: apps/profiles/models.py, apps/profiles/apps.py:9-13, apps/profiles/tests.py:16-22
ER Diagram
This diagram illustrates the one-to-one relationship between the auth_user table and the profiles_profile table.
Sources: apps/profiles/models.py:10-11
Profile Model Fields
The Profile model contains fields for personal information, preferences, and account status.
| Field | Type | Description |
|---|---|---|
user | OneToOneField | A strict one-to-one link to the Django User model. Deleting a User also deletes the associated Profile. |
first_name | CharField | User's first name (max 100 characters). |
last_name | CharField | User's last name (max 100 characters). |
email | EmailField | User's email address (max 255 characters). |
phone | CharField | User's phone number (max 20 characters). |
preferred_sports | TextField | A text field for users to list their preferred sports. |
profile_picture | ImageField | An optional field for uploading a profile picture. |
newsletter_opt_in | BooleanField | A flag indicating if the user is subscribed to the newsletter. Defaults to False. |
account_type | CharField | Defines the user's role. Choices are 'BUYER' (default) or 'SELLER'. |
created_at | DateTimeField | Timestamp for when the profile was created. |
updated_at | DateTimeField | Timestamp for the last update to the profile. |
Sources: apps/profiles/models.py:10-30
Automatic Profile Creation
A Profile is automatically created whenever a new User is saved. This is handled by the create_user_profile signal receiver, which is connected to the post_save signal of the User model. This ensures data integrity and that every user has an associated profile.
Sources: apps/profiles/apps.py:9-13, apps/profiles/tests.py:16-22
Views and URL Routing
The profiles app defines several views to handle displaying, editing, and updating profile data. All views are protected by the @login_required decorator, ensuring only authenticated users can access them.
Sources: apps/profiles/views.py, apps/profiles/urls.py
URL Endpoints
| Path | View Name | URL Name | Description |
|---|---|---|---|
profile/ | profile_detail | profiles:detail | Displays the current user's profile information. |
profile/edit/ | profile_edit | profiles:edit | Renders the form to edit the profile and handles the POST submission. |
profile/ajax/toggle-newsletter/ | toggle_newsletter_ajax | profiles:toggle_newsletter_ajax | AJAX endpoint to toggle the newsletter subscription status. |
profile/ajax/switch-account-type/ | switch_account_type_ajax | profiles:switch_account_type_ajax | AJAX endpoint to switch the user's account type between 'BUYER' and 'SELLER'. |
Sources: apps/profiles/urls.py:3-7
User Interface
The UI consists of two main pages: a detail view and an edit form.
Profile Detail Page
The profile detail page (profile_detail.html) serves as the main dashboard for the user's profile. It displays all the information from the Profile model in a read-only format.
Key features displayed:
- Profile picture (or a placeholder initial).
- Full name and username.
- Membership date (
created_at). - Contact and personal information.
- An iOS-style toggle switch for the newsletter subscription.
- A section to view and switch the account type ('Buyer' or 'Seller').
This page uses JavaScript to handle asynchronous updates for the newsletter toggle and account type switching, providing a seamless user experience without full page reloads.
Sources: apps/profiles/templates/profiles/profile_detail.html, apps/profiles/templates/profiles/profile_detail_new.html
Profile Edit Page
The profile edit page (profile_edit.html) provides a form for users to update their information.
- It uses the
ProfileFormto render input fields forfirst_name,last_name,email,phone,preferred_sports,profile_picture, andnewsletter_opt_in. - The form is submitted via a standard POST request and includes
enctype="multipart/form-data"to support file uploads for the profile picture. - Upon successful submission, the user is redirected back to the profile detail page.
Sources: apps/profiles/templates/profiles/profile_edit.html, apps/profiles/forms.py
Forms
ProfileForm
The ProfileForm is a ModelForm based on the Profile model. It is used in the profile_edit view to validate and save user-submitted data.
Sources: apps/profiles/forms.py:7-38
The form includes the following fields:
first_namelast_nameemailphonepreferred_sportsprofile_picturenewsletter_opt_in
It defines custom widgets with CSS classes (form-control) and placeholders to enhance the user interface. A custom clean_phone method is included to validate the phone number format.
Sources: apps/profiles/forms.py:22-38
Key Functionalities
Account Type Switching
A user can switch their account type between 'BUYER' and 'SELLER'. This is a critical feature as only 'SELLER' accounts can list products. The switch is handled asynchronously.
The flow is as follows:
- User clicks the "Switch to Seller/Buyer Account" button on the profile detail page.
- A JavaScript-powered modal appears to confirm the action, warning 'SELLER' users that switching to 'BUYER' will delete their product listings.
- Upon confirmation, a POST request is sent to the
switch_account_type_ajaxendpoint. - The view validates the request, updates the
account_typeon the user'sProfileobject. - If a user switches from 'SELLER' to 'BUYER', all products created by that user are deleted from the database.
- A JSON response is returned indicating success or failure, and the page reloads to reflect the change.
Sources: apps/profiles/views.py:46-81, apps/profiles/templates/profiles/profile_detail.html:474-565, apps/main/tests.py:270-323
This diagram shows the sequence of events for switching an account type.
Newsletter Subscription Toggle
Users can opt in or out of the newsletter directly from their profile page using a toggle switch. This action is also handled via an AJAX request to prevent a full page reload.
The flow is as follows:
- User clicks the newsletter toggle switch.
- JavaScript sends a POST request to the
toggle_newsletter_ajaxendpoint with the new subscription status. - The view updates the
newsletter_opt_inboolean field on the user'sProfile. - A JSON response is returned, and a toast notification confirms the update on the frontend.
Sources: apps/profiles/views.py:39-44, apps/profiles/templates/profiles/profile_detail_new.html:460-492
This diagram illustrates the newsletter toggle functionality.
Conclusion
The User Profile Management feature is a well-structured and essential component of the Becathlon application. It effectively separates user-specific data from the core authentication model, providing a clean architecture for managing personal information, preferences, and application-specific roles like 'Buyer' and 'Seller'. The use of AJAX for key interactions like account switching and newsletter preferences demonstrates a commitment to a modern, responsive user experience. The automatic creation of profiles via signals ensures data consistency across the platform.