summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRomain Derie <rde@odoo.com>2019-06-03 14:26:02 +0000
committerJeremy Kersten <jke@odoo.com>2019-06-05 05:56:33 +0000
commitd7cd97a9be63ae0a8643400b56d6f9a03285fba6 (patch)
tree112638e0f06aaf4bce3fa7669b37fc0f577f1363
parent2fab076e84ef72fa3482af227e432e6f3885e9a1 (diff)
[IMP] *: new asset for test files, new debug mode (stored in session)
This commit goal is to encapsulate every tour-test into a separate assets bundle that would be called only during tests (command line) or by URL (debug=tests). That way, a lot of .js files would not be loaded anymore uselessly outside test mode and will speed up the page loads (especially in the frontend as the backend do not reload the page anyway). In order to do that, we needed to propagate the `debug` state from page to page. Otherwise, every page change during a test would simply lose the debug mode and the test would stop as the test assets would not be loaded. As we could not add the `&debug=tests` on every link (either hardcoded or preprocess during the rendering), it has been decided to store it in session. Technical summary: 1. `debug` state (currently only stored in URL) will be stored in session. Either when adding the `debug` param in URL (handled with _dispatch) or by starting Odoo with `test-enable` or `test-file` (handled by session init). 2. Once activated (and so set in session), debug mode will remain activated even if not visible in URL (after a page navigation eg). To deactivate it, set its value to nothing, `debug=`. That will exit debug mode (whatever mode it is: debug, assets, tests). 3. As tour-test files are now in a separate bundle, every layout (when needed) should `t-call="web.conditional_assets_tests"`. As it would be redundant and verbose, no `t-if` is needed on the t-call to load it only in test debug mode. That will be handled by `compiled_assets_tests` that will actually do the conditionnal t-call-assets to web.assets_tests, if tests debug mode is activated. 4. In addition to separating the tour-tests files in a separate bundle, we also moved those files to a specific folder under /static/tests/tours next to QUnit tests. 5. Also, tour files will be moved in a specific folder /static/src/js/tours for cleanness purpose (those files will still be kept in their 'normal' assets as needed outside test mode since it is tours). This will be done in the next commit. 6. It is possible to enable multiple debug mode, such as 'tests' and 'assets' together. Simply separate debug modes with a comma, eg '?debug=assets,tests' task-1934445 Comes with https://github.com/odoo/enterprise/pull/4281 Closes #33213
-rw-r--r--addons/hw_proxy/controllers/main.py2
-rw-r--r--addons/point_of_sale/controllers/main.py2
-rw-r--r--addons/point_of_sale/views/pos_templates.xml2
-rw-r--r--addons/stock/controllers/main.py2
-rw-r--r--addons/stock/static/tests/route_tour.js2
-rw-r--r--addons/web/controllers/main.py11
-rw-r--r--addons/web/models/ir_http.py4
-rw-r--r--addons/web/views/webclient_templates.xml11
-rw-r--r--addons/web_settings_dashboard/controllers/main.py2
-rw-r--r--addons/web_settings_dashboard/static/src/xml/dashboard.xml14
-rw-r--r--addons/website/models/ir_qweb.py2
-rw-r--r--addons/website/tests/test_qweb.py5
-rw-r--r--addons/website/views/website_templates.xml8
-rw-r--r--odoo/addons/base/models/assetsbundle.py2
-rw-r--r--odoo/addons/base/models/ir_http.py23
-rw-r--r--odoo/addons/base/models/ir_ui_menu.py2
-rw-r--r--odoo/addons/base/models/ir_ui_view.py2
-rw-r--r--odoo/http.py54
-rw-r--r--odoo/models.py4
19 files changed, 91 insertions, 63 deletions
diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py
index a6c93e2939d..33e20f8a76a 100644
--- a/addons/hw_proxy/controllers/main.py
+++ b/addons/hw_proxy/controllers/main.py
@@ -101,7 +101,7 @@ class Proxy(http.Controller):
<p>The list of connected USB devices as seen by the IoTBox</p>
"""
if debug is None:
- resp += """(<a href="/hw_proxy/status?debug">debug version</a>)"""
+ resp += """(<a href="/hw_proxy/status?debug=1">debug version</a>)"""
devices = subprocess.check_output("lsusb").decode('utf-8').split('\n')
count = 0
resp += "<div class='devices'>\n"
diff --git a/addons/point_of_sale/controllers/main.py b/addons/point_of_sale/controllers/main.py
index 79ec844fdf8..0fca1369384 100644
--- a/addons/point_of_sale/controllers/main.py
+++ b/addons/point_of_sale/controllers/main.py
@@ -12,7 +12,7 @@ _logger = logging.getLogger(__name__)
class PosController(http.Controller):
@http.route('/pos/web', type='http', auth='user')
- def pos_web(self, debug=False, **k):
+ def pos_web(self, **k):
# if user not logged in, log him in
pos_sessions = request.env['pos.session'].search([
('state', '=', 'opened'),
diff --git a/addons/point_of_sale/views/pos_templates.xml b/addons/point_of_sale/views/pos_templates.xml
index dfadf1af349..cb1a8a81a01 100644
--- a/addons/point_of_sale/views/pos_templates.xml
+++ b/addons/point_of_sale/views/pos_templates.xml
@@ -31,12 +31,14 @@
var odoo = {
csrf_token: "<t t-esc="request.csrf_token(None)"/>",
session_info: <t t-raw="session_info"/>,
+ debug: "<t t-esc="debug"/>",
};
</script>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="point_of_sale.pos_assets_backend" t-css="false"/>
<t t-call-assets="point_of_sale.assets"/>
+ <t t-call="web.conditional_assets_tests"/>
<script type="text/javascript" id="loading-script" t-raw="init">
odoo.define('web.web_client', function (require) {
diff --git a/addons/stock/controllers/main.py b/addons/stock/controllers/main.py
index 1d9041e0ed9..e18b0e6da96 100644
--- a/addons/stock/controllers/main.py
+++ b/addons/stock/controllers/main.py
@@ -10,7 +10,7 @@ import json
class BarcodeController(http.Controller):
@http.route(['/stock/barcode/'], type='http', auth='user')
- def a(self, debug=False, **k):
+ def a(self, **k):
if not request.session.uid:
return http.local_redirect('/web/login?redirect=/stock/barcode/')
diff --git a/addons/stock/static/tests/route_tour.js b/addons/stock/static/tests/route_tour.js
index 4e3d305e32d..4647f41a36f 100644
--- a/addons/stock/static/tests/route_tour.js
+++ b/addons/stock/static/tests/route_tour.js
@@ -5,7 +5,7 @@ var tour = require('web_tour.tour');
tour.register('stock', {
test: true,
- url: '/web?debug=assets#action=stock.action_stock_config_settings',
+ url: '/web#action=stock.action_stock_config_settings',
},
[
{
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index ab7ba022379..1b16c64cd4d 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -485,7 +485,7 @@ class Home(http.Controller):
:param unique: this parameters is not used, but mandatory: it is used by the HTTP stack to make a unique request
:return: the menus (including the images in Base64)
"""
- menus = request.env["ir.ui.menu"].load_menus(request.debug)
+ menus = request.env["ir.ui.menu"].load_menus(request.session.debug)
body = json.dumps(menus, default=ustr)
response = request.make_response(body, [
# this method must specify a content-type application/json instead of using the default text/html set because
@@ -542,12 +542,6 @@ class Home(http.Controller):
if not odoo.tools.config['list_db']:
values['disable_database_manager'] = True
- # otherwise no real way to test debug mode in template as ?debug =>
- # values['debug'] = '' but that's also the fallback value when
- # missing variables in qweb
- if 'debug' in values:
- values['debug'] = True
-
response = request.render('web.login', values)
response.headers['X-Frame-Options'] = 'DENY'
return response
@@ -1590,8 +1584,7 @@ class Apps(http.Controller):
action['views'] = [(False, u'form')]
sakey = Session().save_session_action(action)
- debug = '?debug' if req.debug else ''
- return werkzeug.utils.redirect('/web{0}#sa={1}'.format(debug, sakey))
+ return werkzeug.utils.redirect('/web#sa={0}'.format(sakey))
class ReportController(http.Controller):
diff --git a/addons/web/models/ir_http.py b/addons/web/models/ir_http.py
index d4280e7f25a..f2bfc70f9b4 100644
--- a/addons/web/models/ir_http.py
+++ b/addons/web/models/ir_http.py
@@ -17,7 +17,7 @@ class Http(models.AbstractModel):
def webclient_rendering_context(self):
return {
- 'menu_data': request.env['ir.ui.menu'].load_menus(request.debug),
+ 'menu_data': request.env['ir.ui.menu'].load_menus(request.session.debug),
'session_info': json.dumps(self.session_info()),
}
@@ -34,7 +34,7 @@ class Http(models.AbstractModel):
lang = user_context.get("lang")
translations_per_module, _ = request.env['ir.translation'].get_translations_for_webclient(mods, lang)
- menu_json_utf8 = json.dumps(request.env['ir.ui.menu'].load_menus(request.debug), default=ustr, sort_keys=True).encode()
+ menu_json_utf8 = json.dumps(request.env['ir.ui.menu'].load_menus(request.session.debug), default=ustr, sort_keys=True).encode()
translations_json_utf8 = json.dumps(translations_per_module, sort_keys=True).encode()
return {
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 5e322ad2ac9..73776df93f5 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -387,6 +387,14 @@
<xpath expr="//t[@t-call='web._assets_frontend_minimal_js']" position="replace"/>
</template>
+ <!-- Do not direcly call this template, call 'conditional_assets_tests' instead -->
+ <template id="assets_tests" name="Tests Assets">
+ </template>
+
+ <template id="conditional_assets_tests" name="Tests Assets Bundle">
+ <t t-call-assets="web.assets_tests" t-if="'tests' in debug" defer_load="True" />
+ </template>
+
<template id="web.layout" name="Web layout">&lt;!DOCTYPE html&gt;
<html t-att="html_data or {}">
<head>
@@ -400,6 +408,7 @@
<script type="text/javascript">
var odoo = {
csrf_token: "<t t-esc="request.csrf_token(None)"/>",
+ debug: "<t t-esc="debug"/>",
};
</script>
@@ -422,6 +431,7 @@
</script>
<t t-call-assets="web.assets_common_minimal_js" t-css="false" defer_load="True"/>
<t t-call-assets="web.assets_frontend_minimal_js" t-css="false" defer_load="True"/>
+ <t t-call="web.conditional_assets_tests"/>
<t t-call-assets="web.assets_common_lazy" t-css="false" lazy_load="True"/>
<t t-call-assets="web.assets_frontend_lazy" t-css="false" lazy_load="True"/>
</xpath>
@@ -840,6 +850,7 @@
<t t-call-assets="web.assets_backend" t-js="false"/>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
+ <t t-call="web.conditional_assets_tests"/>
<![CDATA[
<!--[if lt IE 10]>
diff --git a/addons/web_settings_dashboard/controllers/main.py b/addons/web_settings_dashboard/controllers/main.py
index 574f9e8fd21..fb1105ba939 100644
--- a/addons/web_settings_dashboard/controllers/main.py
+++ b/addons/web_settings_dashboard/controllers/main.py
@@ -73,7 +73,7 @@ class WebSettingsDashboard(http.Controller):
'share': {
'server_version': release.version,
'expiration_date': expiration_date,
- 'debug': request.debug,
+ 'debug': request.session.debug,
'demo_active': demo_active,
},
'company': {
diff --git a/addons/web_settings_dashboard/static/src/xml/dashboard.xml b/addons/web_settings_dashboard/static/src/xml/dashboard.xml
index b8c8f339ebd..5e55e8d7a87 100644
--- a/addons/web_settings_dashboard/static/src/xml/dashboard.xml
+++ b/addons/web_settings_dashboard/static/src/xml/dashboard.xml
@@ -123,13 +123,13 @@
</div>
</div>
<hr/>
- <a t-if="debug != true" class="oe_activate_debug_mode float-right" href="?debug" >Activate the developer mode</a>
- <br t-if="debug != true"/>
- <a t-if="debug != 'assets'" class="oe_activate_debug_mode float-right" href="?debug=assets" >Activate the developer mode (with assets)</a>
- <br t-if="debug != 'assets'"/>
- <a t-if="debug != false" class="oe_activate_debug_mode float-right" href="/web" >Deactivate the developer mode</a>
- <br t-if="debug != false"/>
- <a t-if="(debug) and !(demo_active)" class="oe_activate_debug_mode float-right o_web_settings_dashboard_force_demo" href="#">Load demo data</a>
+ <div class="text-right">
+ <a t-if="debug.indexOf('1') == -1" class="d-block" href="?debug=1">Activate the developer mode</a>
+ <a t-if="debug.indexOf('assets') == -1" class="d-block" href="?debug=assets">Activate the developer mode (with assets)</a>
+ <a t-if="debug.indexOf('tests') == -1" class="d-block" href="?debug=assets,tests">Activate the developer mode (with tests assets)</a>
+ <a t-if="debug" class="d-block" href="?debug=">Deactivate the developer mode</a>
+ <a t-if="debug and !demo_active" class="o_web_settings_dashboard_force_demo" href="#">Load demo data</a>
+ </div>
</div>
</t>
diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py
index ea33aa114b2..664838afe77 100644
--- a/addons/website/models/ir_qweb.py
+++ b/addons/website/models/ir_qweb.py
@@ -44,7 +44,7 @@ class QWeb(models.AbstractModel):
atts = super(QWeb, self)._post_processing_att(tagName, atts, options)
if options.get('inherit_branding') or options.get('rendering_bundle') or \
- options.get('edit_translations') or options.get('debug') or (request and request.debug):
+ options.get('edit_translations') or options.get('debug') or (request and request.session.debug):
return atts
website = request and getattr(request, 'website', None)
diff --git a/addons/website/tests/test_qweb.py b/addons/website/tests/test_qweb.py
index e3070d9f009..5ca9344aa32 100644
--- a/addons/website/tests/test_qweb.py
+++ b/addons/website/tests/test_qweb.py
@@ -93,7 +93,10 @@ class MockRequest(object):
if not routing:
app.match = werkzeugRaiseNotFound
self.request = MockObject(
- env=env, context=context or {}, db=None, debug=False,
+ env=env, context=context or {}, db=None,
+ session=MockObject(
+ debug=False
+ ),
website=website, httprequest=MockObject(
path='/hello/',
app=app
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index c6f112d554d..3c5904dd034 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -904,7 +904,7 @@
<div class="oe_structure">
<h1 class="container mt32"><t t-esc="status_code"/>: <t t-esc="status_message"/></h1>
</div>
- <t t-if="editable or request.debug">
+ <t t-if="editable or debug">
<t t-call="website.http_error_debug"/>
</t>
</div>
@@ -969,7 +969,7 @@
<li><a href="/contactus">Contact Us</a></li>
</ul>
</div>
- <t t-if="editable or request.debug">
+ <t t-if="editable or debug">
<t t-call="website.http_error_debug"/>
</t>
</div>
@@ -996,7 +996,7 @@
</div>
</div>
- <t t-if="request.debug">
+ <t t-if="debug">
<t t-call="website.http_error_debug"/>
</t>
</div>
@@ -1123,7 +1123,7 @@
</div>
</div>
- <t t-if="editable or request.debug">
+ <t t-if="editable or debug">
<t t-call="website.http_error_debug"/>
</t>
</main>
diff --git a/odoo/addons/base/models/assetsbundle.py b/odoo/addons/base/models/assetsbundle.py
index faf8a3cb8fd..04e85944c0e 100644
--- a/odoo/addons/base/models/assetsbundle.py
+++ b/odoo/addons/base/models/assetsbundle.py
@@ -135,7 +135,7 @@ class AssetsBundle(object):
:returns [(tagName, attributes, content)] if the tag is auto close
"""
response = []
- if debug == 'assets':
+ if debug and 'assets' in debug:
if css and self.stylesheets:
is_css_preprocessed, old_attachments = self.is_css_preprocessed()
if not is_css_preprocessed:
diff --git a/odoo/addons/base/models/ir_http.py b/odoo/addons/base/models/ir_http.py
index 420ba00026f..ac6ccbc9eac 100644
--- a/odoo/addons/base/models/ir_http.py
+++ b/odoo/addons/base/models/ir_http.py
@@ -24,6 +24,9 @@ from odoo.tools import pycompat, consteq
from odoo.tools.mimetypes import guess_mimetype
from odoo.modules.module import get_resource_path, get_module_path
+from odoo.http import ALLOWED_DEBUG_MODES
+from odoo.tools.misc import str2bool
+
_logger = logging.getLogger(__name__)
@@ -126,6 +129,21 @@ class IrHttp(models.AbstractModel):
return auth_method
@classmethod
+ def _handle_debug(cls):
+ # Store URL debug mode (might be empty) into session
+ if 'debug' in request.httprequest.args:
+ debug_mode = []
+ for debug in request.httprequest.args['debug'].split(','):
+ if debug not in ALLOWED_DEBUG_MODES:
+ debug = '1' if str2bool(debug, debug) else ''
+ debug_mode.append(debug)
+ debug_mode = ','.join(debug_mode)
+
+ # Write on session only when needed
+ if debug_mode != request.session.debug:
+ request.session.debug = debug_mode
+
+ @classmethod
def _serve_attachment(cls):
env = api.Environment(request.cr, SUPERUSER_ID, request.context)
attach = env['ir.attachment'].get_serve_attachment(request.httprequest.path, extra_fields=['name', 'checksum'])
@@ -162,6 +180,9 @@ class IrHttp(models.AbstractModel):
@classmethod
def _handle_exception(cls, exception):
+ # in case of Exception, e.g. 404, we don't step into _dispatch
+ cls._handle_debug()
+
# If handle_exception returns something different than None, it will be used as a response
# This is done first as the attachment path may
@@ -182,6 +203,8 @@ class IrHttp(models.AbstractModel):
@classmethod
def _dispatch(cls):
+ cls._handle_debug()
+
# locate the controller method
try:
rule, arguments = cls._find_handler(return_rule=True)
diff --git a/odoo/addons/base/models/ir_ui_menu.py b/odoo/addons/base/models/ir_ui_menu.py
index 7459dd29504..d726ee2cfa1 100644
--- a/odoo/addons/base/models/ir_ui_menu.py
+++ b/odoo/addons/base/models/ir_ui_menu.py
@@ -122,7 +122,7 @@ class IrUiMenu(models.Model):
the menu hierarchy of the current user.
Uses a cache for speeding up the computation.
"""
- visible_ids = self._visible_menu_ids(request.debug if request else False)
+ visible_ids = self._visible_menu_ids(request.session.debug if request else False)
return self.filtered(lambda menu: menu.id in visible_ids)
@api.model
diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py
index 8c5f4809f32..30600ee6bf7 100644
--- a/odoo/addons/base/models/ir_ui_view.py
+++ b/odoo/addons/base/models/ir_ui_view.py
@@ -1356,7 +1356,7 @@ actual arch.
res_company=self.env.company.sudo(),
keep_query=keep_query,
request=request, # might be unbound if we're not in an httprequest context
- debug=request.debug if request else False,
+ debug=request.session.debug if request else '',
json=json,
quote_plus=werkzeug.url_quote_plus,
time=time,
diff --git a/odoo/http.py b/odoo/http.py
index 67243cf5a52..3f4dd6fad27 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -64,6 +64,21 @@ STATIC_CACHE = 60 * 60 * 24 * 7
# To remove when corrected in Babel
babel.core.LOCALE_ALIASES['nb'] = 'nb_NO'
+""" Debug mode is stored in session and should always be a string.
+ It can be activated with an URL query string `debug=<mode>` where
+ mode is either:
+ - 'tests' to load tests assets
+ - 'assets' to load assets non minified
+ - any other truthy value to enable simple debug mode (to show some
+ technical feature, to show complete traceback in frontend error..)
+ - any falsy value to disable debug mode
+
+ You can use any truthy/falsy value from `str2bool` (eg: 'on', 'f'..)
+ Multiple debug modes can be activated simultaneously, separated with
+ a comma (eg: 'tests, assets').
+"""
+ALLOWED_DEBUG_MODES = ['', '1', 'assets', 'tests']
+
#----------------------------------------------------------
# RequestHandler
#----------------------------------------------------------
@@ -143,15 +158,10 @@ def dispatch_rpc(service_name, method, params):
odoo.tools.debugger.post_mortem(odoo.tools.config, sys.exc_info())
raise
-def local_redirect(path, query=None, keep_hash=False, forward_debug=True, code=303):
+def local_redirect(path, query=None, keep_hash=False, code=303):
url = path
if not query:
query = {}
- if request and request.debug:
- if forward_debug:
- query['debug'] = ''
- else:
- query['debug'] = None
if query:
url += '?' + werkzeug.url_encode(query)
if keep_hash:
@@ -345,22 +355,6 @@ class WebRequest(object):
return checked_call(self.db, *args, **kwargs)
return self.endpoint(*args, **kwargs)
- @property
- def debug(self):
- """ Indicates whether the current request is in "debug" mode
- """
- debug = 'debug' in self.httprequest.args
- if debug and self.httprequest.args.get('debug') == 'assets':
- debug = 'assets'
-
- # check if request from rpc in debug mode
- if not debug:
- debug = self.httprequest.environ.get('HTTP_X_DEBUG_MODE')
-
- if not debug and self.httprequest.referrer:
- debug = 'debug' in urls.url_parse(self.httprequest.referrer).decode_query()
- return debug
-
@contextlib.contextmanager
def registry_cr(self):
warnings.warn('please use request.registry and request.cr directly', DeprecationWarning)
@@ -763,7 +757,7 @@ class HttpRequest(WebRequest):
if request.httprequest.method == 'OPTIONS' and request.endpoint and request.endpoint.routing.get('cors'):
headers = {
'Access-Control-Max-Age': 60 * 60 * 24,
- 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, X-Debug-Mode'
+ 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
}
return Response(status=200, headers=headers)
@@ -1038,7 +1032,7 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
def logout(self, keep_db=False):
for k in list(self):
- if not (keep_db and k == 'db'):
+ if not (keep_db and k == 'db') and k != 'debug':
del self[k]
self._default_values()
self.rotate = True
@@ -1049,6 +1043,9 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
self.setdefault("login", None)
self.setdefault("session_token", None)
self.setdefault("context", {})
+ # Force tests debug mode when test mode enabled to load 'assets_tests'
+ test_mode = odoo.tools.config['test_enable'] or odoo.tools.config['test_file']
+ self.setdefault("debug", 'tests' if test_mode else '')
def get_context(self):
"""
@@ -1242,13 +1239,12 @@ class Response(werkzeug.wrappers.Response):
class DisableCacheMiddleware(object):
def __init__(self, app):
self.app = app
+
def __call__(self, environ, start_response):
def start_wrapped(status, headers):
- referer = environ.get('HTTP_REFERER', '')
- parsed = urls.url_parse(referer)
- debug = parsed.query.count('debug') >= 1
-
- if debug:
+ req = werkzeug.wrappers.Request(environ)
+ root.setup_session(req)
+ if req.session and req.session.debug:
new_headers = [('Cache-Control', 'no-cache')]
for k, v in headers:
diff --git a/odoo/models.py b/odoo/models.py
index a2499c6a68d..77701cf676a 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -1237,7 +1237,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
for group_ext_id in not_has_groups:
if group_ext_id == 'base.group_no_one':
# check: the group_no_one is effective in debug mode only
- if user.has_group(group_ext_id) and request and request.debug:
+ if user.has_group(group_ext_id) and request and request.session.debug:
return False
else:
if user.has_group(group_ext_id):
@@ -1246,7 +1246,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
for group_ext_id in has_groups:
if group_ext_id == 'base.group_no_one':
# check: the group_no_one is effective in debug mode only
- if user.has_group(group_ext_id) and request and request.debug:
+ if user.has_group(group_ext_id) and request and request.session.debug:
return True
else:
if user.has_group(group_ext_id):