Enable Dark Mode!
how-to-use-public-controllers-in-odoo-19.jpg
By: Ayana R

How to Use Public Controllers in Odoo 19

Technical Odoo 19 Odoo Enterprises Odoo Community

As Odoo evolves into version 19, its framework continues to empower developers to create dynamic, scalable web applications. One of the foundational elements for exposing public-facing functionality is the Public Controller. These controllers allow you to define HTTP endpoints that are accessible to anyone—without requiring user authentication—making them ideal for websites, APIs, or integration points like product catalogs, contact forms, or public dashboards.

In this blog post, we'll delve into public controllers in Odoo 19, exploring what they are, how to implement them, and best practices.

What Are Public Controllers in Odoo?

Controllers in Odoo are Python classes that handle incoming HTTP requests and route them to appropriate actions, such as rendering templates, processing forms, or returning JSON data. They form the backbone of Odoo's web layer, bridging the frontend (like websites) and backend (models and business logic).

A public controller is a specific type of controller where the auth parameter in the route decorator is set to 'public'. This means:

  • The endpoint is open to the world—no login required.
  • If a user is authenticated, their session is respected.
  • If not, Odoo executes the request under the shared "Public" user, which has limited permissions to ensure security.

Public controllers are essential for eCommerce sites (e.g., shop pages), blogs, forums, or any public API endpoint. They differ from authenticated controllers (auth='user') that require login or bearer-token-protected ones.

Setting Up a Basic Public Controller

To create a public controller, you'll work within a custom Odoo module. Assume you have a module structure like this:

my_module/
+-- __init__.py
+-- __manifest__.py
+-- controllers/
¦   +-- main.py
+-- views/
    +-- public_page.xml (optional for template)

Step 1: Define the Controller Class

In controllers/main.py, import the necessary modules and inherit from odoo.http.Controller:

from odoo import http
from odoo.http import request
class MyPublicController(http.Controller):
    @http.route('/public/hello', type='http', auth='public', methods=['GET'])
    def public_hello(self):
        return "Hello from a public Odoo 19 endpoint!"
  • @http.route(): The decorator defines the URL path (/public/hello), request type ('http' for web pages, 'json' for API), authentication ('public'), and HTTP methods (e.g., ['GET']).
  • Return Values: For HTTP routes, return a string (plain text), a dict (for QWeb templates), or a request.render() call.

Step 2: Register the Controller

In your module's __init__.py:

from . import controllers

Update __manifest__.py to include the controllers path:

{
    'name': 'My Public Module',
    'version': '19.0.1.0.0',
    'depends': ['base', 'website'],  # 'website' for template support
    'data': ['views/public_page.xml'],
    'installable': True,
}

Advanced Features: Parameters, JSON Responses, and Templates

Handling URL Parameters

@http.route('/public/product/<int:product_id>', type='http', auth='public')
def public_product(self, product_id):
    product = request.env['product.template'].sudo().browse(product_id)
    if not product.exists():
        return request.not_found()
    return {
        'product': product,
        'title': f"Details for {product.name}",
    }
  • <int:product_id> extracts an integer from the URL (e.g., /public/product/42).
  • Use sudo() for public access to data, but be cautious—limit fields to avoid exposing sensitive info.
  • Return a dict to render a QWeb template (define it in views/public_page.xml).

Example template (public_page.xml):

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <template id="public_product_template" name="Public Product Page">
        <t t-call="website.layout">
            <div class="container">
                <h1 t-field="title"/>
                <p t-field="product.description_sale"/>
                <p>Price: <span t-field="product.list_price" t-options="{'widget': 'monetary'}"/></p>
            </div>
        </t>
    </template>
</odoo>

CSRF Protection and Security

By default, HTTP POST routes have CSRF tokens. For public forms:

@http.route('/public/contact', type='http', auth='public', methods=['GET', 'POST'], csrf=True)
def public_contact(self, **post):
    if 'name' in post:
        # Process form with sudo() for writes
        request.env['mail.mail'].sudo().create({
            'subject': 'Public Contact',
            'body_html': f"From: {post['name']} - {post['message']}",
            'email_to': 'info@yourcompany.com',
        })
        return request.redirect('/public/thanks')
    return request.render('my_module.contact_form')

Disable CSRF with csrf=False for pure APIs, but enable it for forms to prevent attacks.

Inheriting and Extending Public Controllers

Odoo encourages modularity. To extend an existing public controller (e.g., from the website_sale module):

from odoo.addons.website_sale.controllers.main import WebsiteSale
class ExtendedShop(WebsiteSale):
    @http.route(['/shop'], type='http', auth='public', website=True)
    def shop(self, **kwargs):
        # Add custom logic, e.g., filter products
        kwargs['custom_filter'] = True
        res = super(ExtendedShop, self).shop(**kwargs)
        # Modify res if needed
        return res

Key Rule: Always re-apply @http.route() when overriding—omitting it "unpublishes" the method. This ensures the route stays active in Odoo 19.

Public controllers in Odoo 19 are a powerful, straightforward way to build open, user-friendly web experiences. With minimal code, you can create secure endpoints that scale with your business—whether for eCommerce, content sites, or APIs. As Odoo 19 emphasizes speed and AI-driven enhancements, these controllers will play a key role in modern, integrated apps.

To read more about How to Create and Use HTTP Controllers in Odoo 19, refer to our blog How to Create and Use HTTP Controllers in Odoo 19.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message