How User Notification Preferences Are Stored and Managed in Yappuccino
Yappuccino stores user notification preferences as boolean fields on the one-to-one Profile model and manages updates through a dedicated NotificationSettingsForm handled in the settings view.
The open-source Yappuccino application (available at jafarbekyusupov/yappuccino) implements a straightforward, model-driven approach to managing email notification preferences. Instead of creating separate tables or complex schemas, the system stores these settings directly on the user’s Profile record, making retrieval and updates efficient and atomic. This design ensures that notification settings are always available via request.user.profile without requiring additional database joins.
Database Schema: The Profile Model
At the data layer, Yappuccino defines four boolean fields directly on the Profile model in users/models.py (lines 30-36). These fields control specific email notification channels:
email_comments– alerts for new comments on the user’s postsemail_replies– alerts for replies to the user’s commentsemail_reposts– alerts when someone reposts the user’s contentemail_newsletter– subscription to the weekly newsletter
Because the Profile model maintains a one-to-one relationship with the User model, these preferences are immediately accessible whenever the user object is loaded. The fields default to True or False based on the model definition, and changes are persisted through standard Django ORM save operations.
Form Handling with NotificationSettingsForm
To expose these fields in the UI, Yappuccino uses a ModelForm called NotificationSettingsForm defined in users/forms.py (lines 48-57). This form maps the four boolean model fields to HTML checkboxes, handling both validation and sanitization automatically.
The form accepts a Profile instance as its instance parameter, allowing it to pre-populate checkbox states based on current database values. When form.save() is called, Django writes the cleaned boolean values directly back to the Profile record.
View Logic and Preference Updates
The actual update flow occurs in the settings view located in users/views.py (lines 52-59). The view detects notification-specific submissions by checking for the notification_submit key in the POST data:
elif 'notification_submit' in request.POST:
form = NotificationSettingsForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
# Redirect or render success message
This pattern isolates notification updates from other settings forms on the same page. The view binds the submitted POST data to the current user’s profile instance, validates the input against the form’s field definitions, and persists changes to the database atomically.
Template Rendering in the Settings Page
The frontend implementation lives in users/templates/users/settings.html (lines 85-124). The template renders the NotificationSettingsForm as a group of checkboxes, each bound to the respective model field:
<form method="POST">
{% csrf_token %}
<input type="checkbox" name="email_comments"
{% if user.profile.email_comments %}checked{% endif %}>
<label>New comments on your posts</label>
<input type="checkbox" name="email_replies"
{% if user.profile.email_replies %}checked{% endif %}>
<label>Replies to your comments</label>
<input type="checkbox" name="email_reposts"
{% if user.profile.email_reposts %}checked{% endif %}>
<label>Someone reposts your content</label>
<input type="checkbox" name="email_newsletter"
{% if user.profile.email_newsletter %}checked{% endif %}>
<label>Weekly newsletter</label>
<button type="submit" name="notification_submit">Save Notification Settings</button>
</form>
The template checks each boolean field on user.profile to determine the initial checked state, ensuring the UI reflects the stored preferences.
Working with Notification Preferences Programmatically
Developers can interact with these preferences outside the standard form flow using the Django ORM.
Reading current preferences:
profile = request.user.profile
prefs = {
"comments": profile.email_comments,
"replies": profile.email_replies,
"reposts": profile.email_reposts,
"newsletter": profile.email_newsletter,
}
Updating preferences manually:
profile = request.user.profile
profile.email_comments = True # enable comment notifications
profile.email_newsletter = False # disable newsletter
profile.save() # persist changes
Using the built-in form programmatically:
from users.forms import NotificationSettingsForm
def update_notification(request):
if request.method == "POST":
form = NotificationSettingsForm(
request.POST,
instance=request.user.profile,
)
if form.is_valid():
form.save() # writes all four booleans to DB
Summary
- Storage: Four boolean fields (
email_comments,email_replies,email_reposts,email_newsletter) on the Profile model inusers/models.pystore preferences directly in the database. - Validation: The
NotificationSettingsForminusers/forms.pyhandles input sanitization and maps HTML checkboxes to model fields. - Processing: The settings view in
users/views.pydetectsnotification_submitPOST requests, validates the form, and saves changes. - Presentation: The settings template in
users/templates/users/settings.htmlrenders the form with current values pre-selected. - Access: Preferences are available anywhere via
request.user.profilewithout additional queries.
Frequently Asked Questions
Where are notification preferences stored in Yappuccino?
Notification preferences are stored as boolean columns on the Profile model in users/models.py. The specific fields are email_comments, email_replies, email_reposts, and email_newsletter, which are defined at lines 30-36. Because Profile has a one-to-one relationship with User, these settings are accessible through request.user.profile in any view or template.
What notification types does Yappuccino support?
According to the source code in users/models.py, Yappuccino supports four distinct email notification types: new comments on the user’s posts, replies to the user’s comments, reposts of the user’s content, and a weekly newsletter. Each type corresponds to a separate boolean field on the Profile model, allowing users to toggle channels independently.
How does the settings view handle notification form submissions?
The settings view in users/views.py (lines 52-59) checks for the presence of notification_submit in the POST data to identify notification-specific updates. It then instantiates NotificationSettingsForm with the submitted data and the current user’s profile instance, validates the input, and calls form.save() to persist the boolean values to the database.
Can notification preferences be updated outside the web interface?
Yes. Since the preferences are standard Django model fields, they can be updated programmatically through the ORM by importing the Profile model, setting the boolean attributes (e.g., profile.email_comments = False), and calling profile.save(). Developers can also use NotificationSettingsForm programmatically in custom views or management commands to validate and save changes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →