How to Use Q-Context in Odoo 18: Complete Step by Step Guide
By Braincuber Team
Published on March 21, 2026
Q-Context in Odoo 18 is a powerful tool that passes data from your controller to your QWeb templates. In Odoo 18, using qcontext helps you create more personalized and dynamic pages. When building websites with Odoo, it's important to understand how data gets from your Python code to your web pages. Q-Context lets you define custom variables that aren't part of the default rendering context, giving you more control over how your templates behave or what they display.
What You'll Learn:
- Understanding Q-Context fundamentals and purpose
- How controllers pass data to QWeb templates
- Creating custom controller methods with qcontext
- Extending default Odoo controllers
- Practical examples with Shop page customization
- Best practices for dynamic content management
Understanding Q-Context Fundamentals
In Odoo, qcontext is used to pass extra data from a controller to a QWeb template. It lets you define custom variables that aren't part of the default rendering context. This gives you more control over how your templates behave or what they display. Developers often use qcontext when they need to send additional information from Python code to a webpage, making templates smarter and more dynamic.
Dynamic Data Flow
Pass custom variables from backend Python code to frontend templates for personalized content delivery.
Template Control
Override template behavior and display logic based on custom context variables passed from controllers.
Enhanced Personalization
Create dynamic, user-specific content that adapts based on context data and business logic.
Improved Performance
Reduce template complexity by passing processed data instead of heavy template logic.
Controller and Template Architecture
The controllers handle requests from the browser and return the right content, acting as a bridge between the backend and frontend. When you want to change how a built-in controller works like one that powers the /shop page, you can override it. To do this, you first import the original controller class into your controller.py file, then create a new class that inherits from it.
Import Original Controller
Import the original controller class (e.g., WebsiteSale) into your controller.py file to access existing functionality.
Create Inherited Class
Create a new class that inherits from the original controller to extend or modify its behavior.
Override Methods
Inside the new class, modify specific methods to change or extend the default behavior.
Q-Context Structure and Data Flow
When a user opens the /shop page in Odoo, the qcontext passed to the template contains key information that controls what the template displays. This dictionary contains essential data like selected category, products to show, pagination details, and layout preferences.
{
'search': '',
'order': '',
'category': product.public.category(),
'products': product.template(9, 41, 38, 16),
'pager': {
'page_count': 2,
'page': {
'url': '/shop?',
'num': 1
,
'page_next': {
'url': '/shop/page/2?',
'num': 2
,
'ppg': 20,
'layout_mode': 'grid',
'min_price': 1.98,
'max_price': 4000.0,
'response_template': 'website_sale.products'
}
Practical Implementation: Custom Shop Page
Let's enhance the Shop page by displaying a custom alert message. Using qcontext, we can inject this message directly from the controller into the QWeb template. This enables us to show dynamic content like promotions or stock updates right on the page.
Define Custom Route
Define the route with parameters for page, category, and search functionality using @http.route decorator.
Inherit WebsiteSale
Create a new controller class that inherits from WebsiteSale to access all existing shop functionality.
Override Shop Method
Override the default shop() method to add custom logic and qcontext manipulation.
Call Parent Method
Call the parent shop() method using super() to get the default response, then modify it.
Inject Custom Message
Add your custom data to the qcontext dictionary using response.qcontext['custom_key'] = 'value'.
@http.route([
'/shop',
'/shop/page/',
'/shop/category/',
'/shop/category//page/',
], type='http', auth="public", website=True, sitemap=WebsiteSale.sitemap_shop)
def shop(self, page=0, category=None, search='', min_price=0.0, max_price=0.0, ppg=False, **post):
response = super(WebsiteSaleInherit, self).shop(
page=page, category=category, search=search,
min_price=min_price, max_price=max_price, ppg=ppg, **post
)
# Inject your custom message
if hasattr(response, 'qcontext'):
response.qcontext['offer_message'] = "?? Limited Time Offer: Get 25% off on all items!"
return response
Template Integration
Once the new message is added to qcontext, it appears seamlessly alongside products on the website. Here, we added the offer message as an alert into the template by inheriting the template, using the value passed through qcontext with the key 'offer_message'.
Inherit QWeb Template
Create a template that inherits from the original (e.g., website_sale.products) to add your custom elements.
Access Context Variables
Use
Conditional Display
The message appears only when the offer_message context variable is set, creating dynamic content based on business logic.
| Q-Context Key | Purpose | Usage Example |
|---|---|---|
| search | Stores search query parameters | 'search': request.params.get('search', '') |
| category | Selected product category object | 'category': request.env['product.public.category'].browse([]) |
| products | Product template records to display | 'products': product.template.search([('website_published', '=', True)], limit=20) |
| pager | Pagination information for product listings | 'pager': {'page_count': 2, 'page': 1, 'page_next': 2} |
| custom_data | Any custom variables for dynamic content | 'offer_message': "25% off all items!" |
Advanced Q-Context Techniques
Beyond basic data passing, Q-Context can be used for more advanced scenarios like user-specific content, A/B testing, and dynamic component rendering. These techniques help create more sophisticated and personalized website experiences.
User Personalization
Pass user-specific data like preferences, history, or location to create personalized experiences.
A/B Testing
Use context variables to serve different content versions for testing and optimization.
Dynamic Components
Render different components based on context data for flexible layouts.
Performance Consideration
Be mindful of performance when passing large datasets through qcontext. Consider using lazy loading and caching strategies to maintain fast page load times while providing rich dynamic content.
Frequently Asked Questions
What is the difference between qcontext and regular context in Odoo?
Regular context contains default Odoo data like user info and company details, while qcontext allows you to pass custom variables and data specifically for template rendering and personalization.
Can I modify qcontext data in templates?
Yes, you can modify qcontext data in templates using QWeb directives like t-set, t-if, and t-esc to create dynamic content based on the passed context variables.
How do I debug qcontext issues?
Use print statements in your controller to log qcontext data, and check the template variables using Odoo's debug mode or browser developer tools.
Can qcontext be used with API endpoints?
Yes, qcontext works with both HTTP and JSON API controllers, allowing you to pass custom data to any template rendering context.
What are the limitations of qcontext?
Qcontext is limited to template rendering and cannot modify core Odoo functionality. Complex business logic should remain in controllers rather than templates for better maintainability.
Need Help with Odoo Development?
Our experts can help you implement Q-Context solutions, customize controllers, and create dynamic templates for personalized user experiences.
