Accounts — signals¶
Responsibilities¶
The accounts signals initialize required related records when a new user is created.
They are responsible for:
- creating the default
UserProfile - creating the default
UserSettings - creating the default
UserWorkSchedule - ensuring a stable set of seven
UserWorkDayrows exists
They are not responsible for:
- complex business workflows
- permission logic
- account onboarding decisions
- authentication/session logic
- schedule editing rules
In this app, signals are used only for lightweight, automatic related-model setup.
Main signal handlers¶
ensure_user_related_models¶
Triggered when a User is created.
- Signal
post_save- Sender
User- Trigger condition
- runs only when
created=True - Behavior
- creates
UserProfileif missing - creates
UserSettingsif missing - creates
UserWorkScheduleif missing - ensures weekday rows
0..6exist inUserWorkDay - Idempotency
- uses
get_or_create - only inserts missing
UserWorkDayrows
This guarantees a new user immediately has the related records needed by the frontend and API.
Why this signal exists¶
The frontend and API expect these related rows to exist consistently:
user.profileuser.settingsuser.work_schedule- exactly 7
work_schedule.days
Without this signal, many endpoints would need defensive get_or_create() logic or risk missing-related-object errors.
The signal keeps the default user state stable from the moment the account is created.
Related models created by the signal¶
UserProfile¶
Created automatically for every new user.
Purpose: - stores workforce identity and operational profile data
UserSettings¶
Created automatically for every new user.
Purpose: - stores UI settings and preference overrides
UserWorkSchedule¶
Created automatically for every new user.
Purpose: - stores the user’s weekly schedule container
UserWorkDay¶
Ensured as seven rows for weekdays 0..6.
Purpose: - provides a stable weekly structure for schedule editing and hour calculations
This design avoids sparse or partially initialized schedules.
Signal relationship overview¶
flowchart TD
User[User created]
Signal[post_save signal: ensure_user_related_models]
UserProfile[UserProfile]
UserSettings[UserSettings]
UserWorkSchedule[UserWorkSchedule]
UserWorkDay[UserWorkDay x 7]
User --> Signal
Signal --> UserProfile
Signal --> UserSettings
Signal --> UserWorkSchedule
Signal --> UserWorkDay
Execution flow¶
sequenceDiagram
participant App as User creation
participant Signal as ensure_user_related_models
participant Profile as UserProfile
participant Settings as UserSettings
participant Schedule as UserWorkSchedule
participant Days as UserWorkDay
App->>Signal: post_save(created=True)
Signal->>Profile: get_or_create(user=instance)
Signal->>Settings: get_or_create(user=instance)
Signal->>Schedule: get_or_create(user=instance)
Signal->>Days: check existing weekdays
Signal->>Days: bulk_create missing 0..6 rows
idempotency and safety¶
The signal is intentionally designed to be safe against duplicate creation: • UserProfile.objects.get_or_create(...) • UserSettings.objects.get_or_create(...) • UserWorkSchedule.objects.get_or_create(...)
For UserWorkDay, it: 1. checks which weekdays already exist 2. computes missing weekdays 3. bulk creates only the missing rows
This means: • the signal is safe on first create • repeated saves do not create duplicates • the weekly schedule remains complete even if partially corrupted and repaired via the same logic elsewhere
App registration requirement¶
For the signal to run reliably, the signal module must be imported during app startup.
Typical pattern:
Without this registration, the signal handler may never be connected.