Pular para o conteúdo
Odoo Menu
  • Entrar
  • Experimente grátis
  • Aplicativos
    Finanças
    • Financeiro
    • Faturamento
    • Despesas
    • Planilhas (BI)
    • Documentos
    • Assinar Documentos
    Vendas
    • CRM
    • Vendas
    • PDV Loja
    • PDV Restaurantes
    • Assinaturas
    • Locação
    Websites
    • Criador de Sites
    • e-Commerce
    • Blog
    • Fórum
    • Chat ao Vivo
    • e-Learning
    Cadeia de mantimentos
    • Inventário
    • Fabricação
    • PLM - Ciclo de Vida do Produto
    • Compras
    • Manutenção
    • Qualidade
    Recursos Humanos
    • Funcionários
    • Recrutamento
    • Folgas
    • Avaliações
    • Indicações
    • Frota
    Marketing
    • Redes Sociais
    • Marketing por E-mail
    • Marketing por SMS
    • Eventos
    • Automação de Marketing
    • Pesquisas
    Serviços
    • Projeto
    • Planilhas de Horas
    • Serviço de Campo
    • Central de Ajuda
    • Planejamento
    • Compromissos
    Produtividade
    • Mensagens
    • Aprovações
    • Internet das Coisas
    • VoIP
    • Conhecimento
    • WhatsApp
    Aplicativos de terceiros Odoo Studio Plataforma Odoo Cloud
  • Setores
    Varejo
    • Loja de livros
    • Loja de roupas
    • Loja de móveis
    • Mercearia
    • Loja de ferramentas
    • Loja de brinquedos
    Comida e hospitalidade
    • Bar e Pub
    • Restaurante
    • Fast Food
    • Hospedagem
    • Distribuidor de bebidas
    • Hotel
    Imóveis
    • Imobiliária
    • Escritório de arquitetura
    • Construção
    • Administração de propriedades
    • Jardinagem
    • Associação de proprietários de imóveis
    Consultoria
    • Escritório de Contabilidade
    • Parceiro Odoo
    • Agência de marketing
    • Escritório de advocacia
    • Aquisição de talentos
    • Auditoria e Certificação
    Fabricação
    • Têxtil
    • Metal
    • Móveis
    • Alimentação
    • Cervejaria
    • Presentes corporativos
    Saúde e Boa forma
    • Clube esportivo
    • Loja de óculos
    • Academia
    • Profissionais de bem-estar
    • Farmácia
    • Salão de cabeleireiro
    Comércio
    • Handyman
    • Hardware e Suporte de TI
    • Sistemas de energia solar
    • Sapataria
    • Serviços de limpeza
    • Serviços de climatização
    Outros
    • Organização sem fins lucrativos
    • Agência Ambiental
    • Aluguel de outdoors
    • Fotografia
    • Aluguel de bicicletas
    • Revendedor de software
    Navegar por todos os setores
  • Comunidade
    Aprenda
    • Tutoriais
    • Documentação
    • Certificações
    • Treinamento
    • Blog
    • Podcast
    Empodere a Educação
    • Programa de educação
    • Scale Up! Jogo de Negócios
    • Visite a Odoo
    Obtenha o Software
    • Baixar
    • Comparar edições
    • Releases
    Colaborar
    • Github
    • Fórum
    • Eventos
    • Traduções
    • Torne-se um parceiro
    • Serviços para parceiros
    • Cadastre seu escritório contábil
    Obtenha os serviços
    • Encontre um parceiro
    • Encontre um Contador
    • Conheça um consultor
    • Serviços de Implementação
    • Referências de Clientes
    • Suporte
    • Upgrades
    Github YouTube Twitter Linkedin Instagram Facebook Spotify
    +1 (650) 691-3277
    Faça uma demonstração
  • Preços
  • Ajuda

Odoo is the world's easiest all-in-one management software.
It includes hundreds of business apps:

  • CRM
  • e-Commerce
  • Financeiro
  • Inventário
  • PoS
  • Projeto
  • MRP
All apps
É necessário estar registrado para interagir com a comunidade.
Todas as publicações Pessoas Emblemas
Marcadores (Ver tudo)
odoo accounting v14 pos v15
Sobre este fórum
É necessário estar registrado para interagir com a comunidade.
Todas as publicações Pessoas Emblemas
Marcadores (Ver tudo)
odoo accounting v14 pos v15
Sobre este fórum
Ajuda

Extended "shop" controller executes (confirmed by log), but the view ignores the modified "qcontext" (even with request.render)

Inscrever

Seja notificado quando houver atividade nesta publicação

Esta pergunta foi sinalizada
filter
3 Respostas
962 Visualizações
Avatar
Jose Luis

Hello everyone,

I'm learning Odoo development and I've run into a very strange issue that I haven't been able to solve, even after a clean reinstall of the system. I would greatly appreciate your help and expertise.

Environment:

  • Odoo Version: 19 Community
  • Setup: Official Windows Installer
  • Context: Local development environment on C:\Odoo19 (to avoid permission issues).

Objective: To make the product search on the shop (/shop) more precise by searching only for whole words.

The Problem in Action:

When I search for the term "ram", Odoo's default broad search finds the substring "ram" anywhere. This returns incorrect results like "Heramienta" (Spanish for "tool") and "Programa" (Spanish for "program").

The Log Evidence:

The strangest part is that, at the same time, the server log (odoo.log) proves that my custom controller is executing and that my Python filtering logic is perfect. The list of products my code generates is correct, containing only RAM products.

Summary of the Problem:

In short: the code executes correctly, it filters the product list perfectly (confirmed by the log), but the final webpage ignores this correct list and displays the incorrect one. Even using "request.render()" to force a re-render of the template, the visual result does not change.

My Code "(controllers/ main.py)":


# -*- coding: utf-8 -*-

import logging

import re

from odoo import http

from odoo.http import request

from odoo.addons.website_sale.controllers.main import WebsiteSale


_logger = logging.getLogger(__name__)


class CustomWebsiteSearch(WebsiteSale):


    @http.route([

        '/shop',

        '/shop/page/<int:page>',

        '/shop/category/<model("product.public.category"):category>',

        '/shop/category/<model("product.public.category"):category>/page/<int: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(CustomWebsiteSearch, self).shop(

            page=page, category=category, search=search, min_price=min_price,

            max_price=max_price, ppg=ppg, **post

        )


        if not search or not response.qcontext.get('products'):

            return response


        _logger.info("--- 1. Netdata Controller INITIALIZED for: '%s' ---", search)


        all_products = response.qcontext['products']

        term = search.lower()

        relevant_products = []


        for product in all_products:

            pattern = r'\b' + re.escape(term) + r'\b'

            if re.search(pattern, product.name.lower()):

                relevant_products.append(product)


        _logger.info("--- 2. Products AFTER filter: %s ---", [p.name for p in relevant_products])

       

        qcontext = response.qcontext

        qcontext['products'] = http.request.env['product.template'].browse([p.id for p in relevant_products])

        qcontext['search_count'] = len(relevant_products)


        return request.render('website_sale.products', qcontext)


What could cause Odoo to ignore the "return request.render(...)" and fail to display the updated data from "qcontext", even when the logs prove the logic is correct and executing? Is this a known issue in Odoo 19 Community? Could it be a conflict with the theme or a cache that isn't being cleared properly?

0
Avatar
Cancelar
Jose Luis
Autor

Hi Christoph Farnleitner,

Thank you so much! Your answer was the final breakthrough I needed to solve this problem after being stuck for a long time.

You were absolutely right about the bins key. That was the crucial piece of the puzzle I was missing.

My log was showing a perfectly filtered list of products, but the shop page was still incorrect. I was updating qcontext['products'] but, just as you pointed out, I was completely forgetting to update the grid layout calculation stored in bins. Odoo was trying to use an old, large layout (bins) for a new, small list of products, which was causing the visual error.

After seeing your code, I finally understood that I had to recalculate the bins using TableCompute().process() after I had my final, filtered list of products.

A coworker helped me refine the logic to also handle the pagination correctly (by using the full search_product list first and then sorting/paginating). The final, working code now includes your essential advice. The search is now working perfectly, sorting the exact matches to the top.

I couldn't have solved it without your insight. Thank you for taking the time to share your expertise and pointing me in the right direction!

Avatar
Jose Luis
Autor Melhor resposta

Hi Cybrosys Techno Solutions

Thank you so much for your detailed response!

Your explanation about the AJAX and OWL rendering in Odoo 19 was the "aha!" moment that helped me understand the root cause of the problem. I was completely focused on the backend code and didn't realize the frontend was replacing my results after my controller had already done its job perfectly.

I tried overriding _get_search_domain as you suggested. For some strange reason on my specific local installation, the method was never executed (I confirmed this with logs). It seems my environment has a conflict with overriding internal controller methods that don't have a route.

However, your diagnosis that the frontend was replacing my results was 100% correct. It led me to understand that I needed to update more than just the product list. Following your lead, another user pointed out that I also needed to recalculate the bins variable, and that was the final key to the solution.

I really appreciate you taking the time to explain the 'why' behind the problem. It was a crucial step in finding the final solution. Thank you!

0
Avatar
Cancelar
Avatar
Cybrosys Techno Solutions Pvt.Ltd
Melhor resposta

Hi,


In Odoo 19, your issue happens because the /shop page uses AJAX and OWL rendering, which reloads product results after your controller runs. Even though your Python filtering works, the frontend replaces your filtered list with the default one.


The proper fix is to override Odoo’s search domain before products are loaded instead of re-rendering the template. By customizing the _get_search_domain() method, you can apply whole-word filtering that works with Odoo’s frontend logic.


Try the following code.


# -*- coding: utf-8 -*-

import re

import logging

from odoo import http

from odoo.http import request

from odoo.addons.website_sale.controllers.main import WebsiteSale


_logger = logging.getLogger(__name__)


class CustomWebsiteSearch(WebsiteSale):


    def _get_search_domain(self, search, category, attrib_values, search_in_description=True):

        domain = super()._get_search_domain(search, category, attrib_values, search_in_description)

        if search:

            pattern = r'\b' + re.escape(search.lower()) + r'\b'

            products = request.env['product.template'].sudo().search([])

            filtered_ids = [p.id for p in products if re.search(pattern, p.name.lower())]

            domain = [('id', 'in', filtered_ids)] if filtered_ids else [('id', '=', 0)]

            _logger.info("Whole-word search applied for '%s' -> %s", search, filtered_ids)

        return domain



* Add this controller to your custom module.

* Restart Odoo and upgrade the module.

* Search in /shop — now only exact word matches (e.g., “ram”) will appear.



Hope it helps



0
Avatar
Cancelar
Avatar
Christoph Farnleitner
Melhor resposta

There is more to the /shop/... routes than is covered by your source - see also https://github.com/odoo/odoo/blob/19.0/addons/website_sale/controllers/main.py#L487.

What's most crucial to your scenario is the bins key.

A working source - but far from being optimized nor covering all aspects such as filters etc. - is:

# -*- coding: utf-8 -*-

import logging
import re
from odoo.tools import lazy
from odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale, TableCompute

_logger = logging.getLogger(__name__)


class CustomWebsiteSearch(WebsiteSale):
    @http.route([
        '/shop',
        '/shop/page/<int:page>',
        '/shop/category/<model("product.public.category"):category>',
        '/shop/category/<model("product.public.category"):category>/page/<int: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(CustomWebsiteSearch, self).shop(
            page=page, category=category, search=search, min_price=min_price,
            max_price=max_price, ppg=ppg, **post
        )

        website = request.env['website'].get_current_website()
        ppr = website.shop_ppr or 4

        if not search or not response.qcontext.get('products'):
            return response

        _logger.info("--- 1. Netdata Controller INITIALIZED for: '%s' ---", search)
        all_products = response.qcontext['products']
        term = search.lower()
        relevant_products = []
        for product in all_products:
            pattern = r'\b' + re.escape(term) + r'\b'
            if re.search(pattern, product.name.lower()):
                relevant_products.append(product)

        _logger.info("--- 2. Products AFTER filter: %s ---", [p.name for p in relevant_products])
        qcontext = response.qcontext
        qcontext['products'] = http.request.env['product.template'].browse([p.id for p in relevant_products])
        qcontext['search_product'] = http.request.env['product.template'].browse([p.id for p in relevant_products])
        qcontext['bins'] = lazy(lambda: TableCompute().process(relevant_products, ppg, ppr))
        qcontext['search_count'] = len(relevant_products)
        return request.render('website_sale.products', qcontext)
0
Avatar
Cancelar
Está gostando da discussão? Não fique apenas lendo, participe!

Crie uma conta hoje mesmo para aproveitar os recursos exclusivos e interagir com nossa incrível comunidade!

Inscreva-se
Publicações relacionadas Respostas Visualizações Atividade
cbbbbggf
filter
Avatar
0
nov. 25
2
Factura en estado "EN PROCESO DE PAGO"
filter
Avatar
0
nov. 25
2
Simultaneous search criteria across companies and persons Resolvido
filter
Avatar
Avatar
1
out. 25
792
Differentiating subscription invoices from one-shot services Resolvido
filter
Avatar
Avatar
Avatar
3
set. 25
1100
How to filter contact those parent are in archive stage Resolvido
filter
Avatar
Avatar
1
set. 25
2353
Comunidade
  • Tutoriais
  • Documentação
  • Fórum
Open Source
  • Baixar
  • Github
  • Runbot
  • Traduções
Serviços
  • Odoo.sh Hosting
  • Suporte
  • Upgrade
  • Desenvolvimentos personalizados
  • Educação
  • Encontre um Contador
  • Encontre um parceiro
  • Torne-se um parceiro
Sobre nós
  • Nossa empresa
  • Ativos da marca
  • Contato
  • Empregos
  • Eventos
  • Podcast
  • Blog
  • Clientes
  • Legal • Privacidade
  • Segurança
الْعَرَبيّة Català 简体中文 繁體中文 (台灣) Čeština Dansk Nederlands English Suomi Français Deutsch हिंदी Bahasa Indonesia Italiano 日本語 한국어 (KR) Lietuvių kalba Język polski Português (BR) română русский язык Slovenský jazyk slovenščina Español (América Latina) Español ภาษาไทย Türkçe українська Tiếng Việt

Odoo é um conjunto de aplicativos de negócios em código aberto que cobre todas as necessidades de sua empresa: CRM, comércio eletrônico, contabilidade, estoque, ponto de venda, gerenciamento de projetos, etc.

A proposta de valor exclusiva Odoo é ser, ao mesmo tempo, muito fácil de usar e totalmente integrado.

Site feito com

Odoo Experience on YouTube

1. Use the live chat to ask your questions.
2. The operator answers within a few minutes.

Live support on Youtube
Watch now