Feature: Recommendation Engine
Relevant source files
The following files were used as context for generating this wiki page:The Becathlon Recommendation Engine is designed to provide users with personalized product suggestions, enhancing the shopping experience. The feature is primarily integrated into the main homepage for authenticated users, offering recommendations based on their profile preferences and product popularity. A secondary, simpler recommendation view also exists as a standalone page.
The core purpose is to drive user engagement by showcasing relevant products. For authenticated users, this is achieved by displaying a "Recommended for You" section directly on the homepage.
Sources: README.md, apps/main/templates/main/home.html:190-196, apps/main/views.py:24-64
System Architecture
The recommendation functionality is split between two Django apps: main and recommendation.
- Main App Integration: The primary and more complex recommendation logic resides within the
mainapp. It is executed as part of the homepage view and leverages user profile data to generate tailored suggestions. - Recommendation App: This app provides a self-contained, simpler recommendation view at a dedicated URL. It shows the newest products in the catalog.
The following diagram illustrates the high-level request flow for the homepage recommendations.
This diagram shows the process of generating and displaying recommendations on the homepage for an authenticated user.
Sources: apps/main/views.py, apps/main/templates/main/home.html
Homepage Recommendations
This is the primary implementation of the recommendation engine, displayed to logged-in users on the main homepage.
Sources: apps/main/views.py:24-64, apps/main/templates/main/home.html:190-196
View Logic (apps/main/views.py)
The logic is handled by the get_recommendations(user) helper function, which is called by the home view.
The recommendation strategy follows these steps:
- Fetch User Preferences: It retrieves the
preferred_sportsfrom the user's profile. - Personalized Filtering: If preferred sports are set, it filters products belonging to those sport categories. It also excludes products created by the user themselves.
- Popularity Ranking: The filtered products are annotated with an order count (
num_orders) and sorted first by the number of orders (descending), then by creation date (descending). - Fallback Mechanism: If the user has no preferred sports or the personalized query yields no results, the system falls back to a simpler logic: it recommends the 5 most recently added products (excluding the user's own products).
- Limit Results: In all cases, a maximum of 5 products are returned.
The sequence of operations within the get_recommendations function is detailed below.
This diagram shows the sequence of actions taken by the get_recommendations function to generate a list of products.
Sources: apps/main/views.py:24-64
Template Integration (apps/main/templates/main/home.html)
The homepage template conditionally renders the recommendation section for authenticated users. It uses a Django include tag to render the list of recommended products.
{% if user.is_authenticated %}
<section class="section" id="recommendations-section">
<h2 class="section-title">Recommended for You</h2>
<div class="recommendations-wrapper">
{% include "recommendation/product_recommendations.html" with recommendations=recommendations %}
</div>
</section>
{% endif %}
Sources: apps/main/templates/main/home.html:190-196
The actual rendering of each product card is handled by the product_recommendations.html template.
Standalone Recommendation View
The recommendation app also provides its own simple view and URL. This implementation is independent of the homepage logic.
Sources: apps/recommendation/views.py, apps/recommendation/urls.py
URL Configuration
The feature is accessible via the /recommendations/ path.
| Path | View Function | Name | App Namespace |
|---|---|---|---|
recommendations/ | product_recommendations | product_recommendations | recommendation |
Sources: apps/recommendation/urls.py:4
View Logic (apps/recommendation/views.py)
The product_recommendations view is restricted to logged-in users via the @login_required decorator. Its logic is straightforward:
- Fetch the 5 most recently created products from the database.
- Render the
product_recommendations.htmltemplate, passing the products in therecommendationscontext variable.
# apps/recommendation/views.py:4-13
@login_required
def product_recommendations(request):
"""
A simple view that returns the 5 newest products as recommendations.
This is a basic implementation and can be expanded.
"""
# For now, just recommend the 5 newest products
recommendations = Product.objects.order_by('-created_at')[:5]
return render(request, 'recommendation/product_recommendations.html', {
'recommendations': recommendations
})
Sources: apps/recommendation/views.py:4-13
Template Rendering
Both recommendation implementations use the same template file to render the final HTML.
Sources: apps/recommendation/templates/recommendation/product_recommendations.html
product_recommendations.html
This template is responsible for displaying the list of recommended products. It iterates over the recommendations context variable and creates a product card for each item.
Key features:
- Displays the product image, name, and price.
- Provides a link to the product's detail page.
- Shows a fallback message if no recommendations are available.
<!-- apps/recommendation/templates/recommendation/product_recommendations.html:43-56 -->
<div class="recs-grid">
{% for p in recommendations %}
<div class="rec-card">
<a href="{% url 'product_detail' p.id %}" class="rec-link">
{% if p.image_url %}
<img src="{{ p.image_url }}" alt="{{ p.name }}">
{% else %}
<div class="rec-no-image">─</div>
{% endif %}
<div class="rec-card-content">
<div class="rec-name">{{ p.name }}</div>
<div class="rec-price">${{ p.price }}</div>
</div>
</a>
</div>
{% empty %}
<p style="text-align: center; color: rgba(255, 255, 255, 0.5); padding: 2rem;">No recommendations available at this time.</p>
{% endfor %}
</div>
Sources: apps/recommendation/templates/recommendation/product_recommendations.html:43-56
Summary
The Becathlon recommendation engine currently exists in two forms. The primary, user-facing feature is integrated into the homepage and uses a combination of user preferences (preferred_sports) and product popularity (order count) to generate a personalized list of recommendations. A simpler, standalone view also exists, which merely displays the five newest products. Both systems utilize a shared template for rendering the final output. The architecture allows for future enhancements to the recommendation logic without altering the frontend integration points.
Sources: apps/main/views.py, apps/recommendation/views.py, README.md