Перейти к содержимому
Odoo Меню
  • Войти
  • Попробовать бесплатно
  • Модули
    Финансы
    • Бухгалтерия
    • Выставление счетов
    • Расходы
    • Таблицы
    • Документооборот
    • Подпись
    Продажи
    • CRM
    • Продажи
    • POS Магазин
    • POS Ресторан
    • Подписки
    • Аренда
    Вебсайты
    • Конструктор вебсайтов
    • eCommerce
    • Блог
    • Форум
    • Онлайн-чат
    • Электронное обучение
    Логистика
    • Склад
    • Производство
    • PLM
    • Закупки
    • Обслуживание
    • Качество
    Отдел кадров
    • Сотрудники
    • Подбор персонала
    • Отпуска
    • Оценка персонала
    • Реферальная программа
    • Автопарк
    Маркетинг
    • SMM
    • E-mail рассылки
    • СМС рассылки
    • Мероприятия
    • Автоматизация маркетинга
    • Опросы
    Услуги
    • Проекты
    • Табели
    • Выездной сервис
    • Поддержка
    • Планирование
    • Встречи
    Продуктивность
    • Обсуждения
    • Согласование
    • IoT
    • VoIP-телефония
    • Knowledge
    • WhatsApp
    Сторонние приложения Модуль Студия Odoo Платформа Odoo Cloud
  • Индустрии
    Розничная торговля
    • Книжный магазин
    • Магазин одежды
    • Мебельный магазин
    • Продуктовый магазин
    • Строительный магазин
    • Магазин игрушек
    Гостинично-ресторанный бизнес
    • Бар и паб
    • Ресторан
    • Фастфуд
    • Гостевой дом
    • Дистрибьютор напитков
    • Отель
    Недвижимость
    • Агентство недвижимости
    • Архитектурное бюро
    • Строительство
    • Управление недвижимостью
    • Ландшафтный дизайн
    • Товарищество собственников жилья
    Консалтинг
    • Бухгалтерская фирма
    • Партнер Odoo
    • Маркетинговое агентство
    • Юридическая фирма
    • Подбор персонала
    • Аудиторское бюро
    Производство
    • Текстиль
    • Металл
    • Мебель
    • Продукты питания
    • Пивоварня
    • Корпоративные сувениры
    Здоровье и фитнес
    • Спортивный комплекс
    • Магазин оптики
    • Фитнес-клуб
    • Велнес-центр
    • Аптека
    • Салон красоты
    Услуги
    • Специалист по бытовым услугам
    • Продажа и обслуживание IT-оборудования
    • Солнечные энергосистемы
    • Производство обуви
    • Клининг
    • Системы ОВКВ
    Прочее
    • Некоммерческая организация
    • Консалтинг в сфере устойчивого развития
    • Аренда рекламных щитов
    • Бизнес по фотосъемке
    • Прокат велосипедов
    • Реселлер программного обеспечения
    Все индустрии
  • Community
    Обучение
    • Видео уроки
    • Документация
    • Сертификация
    • Тренинг
    • Блог
    • Подкаст
    Образование и развитие
    • Образовательная программа
    • Деловая игра Scale Up!
    • Экскурсия в офис Odoo
    ПО
    • Скачать
    • Сравнить версии
    • Релизы
    Сотрудничество
    • Github
    • Форум
    • Мероприятия
    • Перевод
    • Стать партнером
    • Услуги для партнеров
    • Зарегистрировать бухгалтерскую фирму
    Услуги
    • Найти партнера
    • Найти бухгалтера
    • Встреча с экспертом
    • Услуги по внедрению
    • Отзывы клиентов
    • Поддержка
    • Обновления
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +1 (650) 691-3277
    Заказать демонстрацию
  • Цены
  • Поддержка

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

  • CRM
  • e-Commerce
  • Бухгалтерия
  • Склад
  • PoS
  • Проекты
  • MRP
All apps
Чтобы взаимодействовать с сообществом, необходимо зарегистрироваться.
Все посты Люди Значки
Теги (Смотреть все)
odoo accounting v14 pos v15
Об этом форуме
Чтобы взаимодействовать с сообществом, необходимо зарегистрироваться.
Все посты Люди Значки
Теги (Смотреть все)
odoo accounting v14 pos v15
Об этом форуме
Помощь

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

Подписаться

Получайте уведомления о появлении активности в этом посте

Этот вопрос был отмечен
filter
3 Ответы
933 Представления
Аватар
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
Аватар
Отменить
Jose Luis
Автор

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!

Аватар
Jose Luis
Автор Лучший ответ

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
Аватар
Отменить
Аватар
Cybrosys Techno Solutions Pvt.Ltd
Лучший ответ

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
Аватар
Отменить
Аватар
Christoph Farnleitner
Лучший ответ

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
Аватар
Отменить
Не оставайтесь в стороне – присоединяйтесь к обсуждению!

Создайте аккаунт сегодня, чтобы получить доступ к эксклюзивным функциям и стать частью нашего замечательного сообщества!

Регистрация
Похожие посты Ответы Просмотры Активность
cbbbbggf
filter
Аватар
0
нояб. 25
2
Factura en estado "EN PROCESO DE PAGO"
filter
Аватар
0
нояб. 25
2
Simultaneous search criteria across companies and persons Решено
filter
Аватар
Аватар
1
окт. 25
780
Differentiating subscription invoices from one-shot services Решено
filter
Аватар
Аватар
Аватар
3
сент. 25
1076
How to filter contact those parent are in archive stage Решено
filter
Аватар
Аватар
1
сент. 25
2345
Сообщество
  • Видео уроки
  • Документация
  • Форум
Открытый исходный код
  • Скачать
  • Github
  • Runbot
  • Перевод
Услуги
  • Хостинг Odoo.sh
  • Поддержка
  • Обновление
  • Индивидуальные решения по доработке
  • Образование
  • Найти бухгалтера
  • Найти партнера
  • Стать партнером
О нас
  • Наша компания
  • Активы бренда
  • Cвяжитесь с нами
  • Вакансии
  • Мероприятия
  • Подкаст
  • Блог
  • Клиенты
  • Правовые документы • Конфиденциальность
  • Безопасность
الْعَرَبيّة 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 – это набор бизнес-модулей с открытым исходным кодом, который закроет все потребности вашей компании: CRM, E-commerce, Бухгалтерия, Склад, POS, управление проектами и др.

Odoo сочетает в себе простоту использования и полную интеграцию всех бизнес-процессов в одной системе.

Website made with

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