diff options
| author | Thibault Delavallée <tde@odoo.com> | 2017-05-19 12:51:48 +0200 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2017-08-08 14:23:58 +0200 |
| commit | 014b5c9f7c2f0a5c9741569525364ff9cd6cb4cc (patch) | |
| tree | 20defe1809c23177e60c5da655c3a0d959e73cb0 | |
| parent | da8d418ff08aa55c7378887c9a5a06a5d12b72c0 (diff) | |
[MOV] website, http_routing: move (un)slug support to http_routing
Slug and unslug API is now available in http_routing. Indeed there is no
link to any website or any reason to not support slufigied URLs when
website is not installed. A new unslug_url method is added as a tool
coming from an embedded method from website. Doing it allows to have all
slug related methods defined at the same point.
Support of slug and unslug in qweb rendering is also moved directly in
http_routing version of ir_ui_view instead of website inheritance. This
is done in order to keep things coherent.
Some code from website about ModelConverter is also moved. Indeed both
versions of ir_http uses some kind of placeholder to store the uid
when converting urls to python. This commit unifies it by using the
website one directly in base to simplify the override.
This commit also updates all module importing slug. Enterprise modules
will have to be updated, see related commit.
34 files changed, 171 insertions, 151 deletions
diff --git a/addons/http_routing/models/__init__.py b/addons/http_routing/models/__init__.py index 67dee8c60db..c13771d0d78 100644 --- a/addons/http_routing/models/__init__.py +++ b/addons/http_routing/models/__init__.py @@ -1,2 +1,5 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import ir_http +from . import ir_ui_view diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py new file mode 100644 index 00000000000..c444d7c95ff --- /dev/null +++ b/addons/http_routing/models/ir_http.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- + +import re +import unicodedata + +# optional python-slugify import (https://github.com/un33k/python-slugify) +try: + import slugify as slugify_lib +except ImportError: + slugify_lib = None + +from odoo import api, models +from odoo.addons.base.ir.ir_http import RequestUID, ModelConverter +from odoo.http import request +from odoo.tools import ustr + + +# ------------------------------------------------------------ +# Slug API +# ------------------------------------------------------------ + +def slugify(s, max_length=None): + """ Transform a string to a slug that can be used in a url path. + This method will first try to do the job with python-slugify if present. + Otherwise it will process string by stripping leading and ending spaces, + converting unicode chars to ascii, lowering all chars and replacing spaces + and underscore with hyphen "-". + :param s: str + :param max_length: int + :rtype: str + """ + s = ustr(s) + if slugify_lib: + # There are 2 different libraries only python-slugify is supported + try: + return slugify_lib.slugify(s, max_length=max_length) + except TypeError: + pass + uni = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore').decode('ascii') + slug_str = re.sub('[\W_]', ' ', uni).strip().lower() + slug_str = re.sub('[-\s]+', '-', slug_str) + + return slug_str[:max_length] + + +def slug(value): + if isinstance(value, models.BaseModel): + if isinstance(value.id, models.NewId): + raise ValueError("Cannot slug non-existent record %s" % value) + # [(id, name)] = value.name_get() + identifier, name = value.id, value.display_name + else: + # assume name_search result tuple + identifier, name = value + slugname = slugify(name or '').strip().strip('-') + if not slugname: + return str(identifier) + return "%s-%d" % (slugname, identifier) + +# NOTE: as the pattern is used as it for the ModelConverter (ir_http.py), do not use any flags +_UNSLUG_RE = re.compile(r'(?:(\w{1,2}|\w[A-Za-z0-9-_]+?\w)-)?(-?\d+)(?=$|/)') + + +def unslug(s): + """Extract slug and id from a string. + Always return un 2-tuple (str|None, int|None) + """ + m = _UNSLUG_RE.match(s) + if not m: + return None, None + return m.group(1), int(m.group(2)) + + +def unslug_url(s): + """ From /blog/my-super-blog-1" to "blog/1" """ + parts = s.split('/') + if parts: + unslug_val = unslug(parts[-1]) + if unslug_val[1]: + parts[-1] = str(unslug_val[1]) + return '/'.join(parts) + return s + + +class ModelConverter(ModelConverter): + + def __init__(self, url_map, model=False, domain='[]'): + super(ModelConverter, self).__init__(url_map, model) + self.domain = domain + self.regex = _UNSLUG_RE.pattern + + def to_url(self, value): + return slug(value) + + def to_python(self, value): + matching = re.match(self.regex, value) + _uid = RequestUID(value=value, match=matching, converter=self) + record_id = int(matching.group(2)) + env = api.Environment(request.cr, _uid, request.context) + if record_id < 0: + # limited support for negative IDs due to our slug pattern, assume abs() if not found + if not env[self.model].browse(record_id).exists(): + record_id = abs(record_id) + return env[self.model].browse(record_id) diff --git a/addons/http_routing/models/ir_ui_view.py b/addons/http_routing/models/ir_ui_view.py new file mode 100644 index 00000000000..549f75e2f73 --- /dev/null +++ b/addons/http_routing/models/ir_ui_view.py @@ -0,0 +1,16 @@ +# -*- coding: ascii -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models +from odoo.addons.http_routing.models.ir_http import slug, unslug_url + + +class IrUiView(models.Model): + _inherit = ["ir.ui.view"] + + @api.model + def _prepare_qcontext(self): + qcontext = super(IrUiView, self)._prepare_qcontext() + qcontext['slug'] = slug + qcontext['unslug_url'] = unslug_url + return qcontext diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 555a23be2cf..044f1f66d26 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1914,7 +1914,7 @@ class MailThread(models.AbstractModel): handle ir ui views. """ values = kwargs.pop('values', None) or dict() try: - from odoo.addons.website.models.website import slug + from odoo.addons.http_routing.models.ir_http import slug values['slug'] = slug except ImportError: values['slug'] = lambda self: self.id diff --git a/addons/survey/models/survey.py b/addons/survey/models/survey.py index 84692c63f9d..c440c67862d 100644 --- a/addons/survey/models/survey.py +++ b/addons/survey/models/survey.py @@ -11,10 +11,9 @@ from itertools import product from werkzeug import urls from odoo import api, fields, models, tools, SUPERUSER_ID, _ +from odoo.addons.http_routing.models.ir_http import slug from odoo.exceptions import UserError, ValidationError -from odoo.addons.website.models.website import slug - from odoo.tools import pycompat email_validator = re.compile(r"[^@]+@[^@]+\.[^@]+") diff --git a/addons/survey/tests/test_survey.py b/addons/survey/tests/test_survey.py index 04a65a02562..c7c4478248c 100644 --- a/addons/survey/tests/test_survey.py +++ b/addons/survey/tests/test_survey.py @@ -9,10 +9,9 @@ from itertools import product from werkzeug import urls from odoo import _ +from odoo.addons.http_routing.models.ir_http import slug from odoo.exceptions import UserError from odoo.tests.common import TransactionCase -from odoo.addons.website.models.website import slug - from odoo.tools import pycompat diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index acc5e75a4d4..d1d75bea159 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -17,7 +17,7 @@ from odoo import http, models from odoo import fields from odoo.http import request -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug from odoo.addons.web.controllers.main import WebClient, Binary, Home from odoo.tools import pycompat, OrderedSet diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 15e751e2b09..870ec4952bc 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -3,7 +3,6 @@ import logging import os -import re import traceback import werkzeug @@ -14,12 +13,12 @@ import odoo from odoo import api, models from odoo import SUPERUSER_ID from odoo.http import request -from odoo.tools import config, pycompat +from odoo.tools import config from odoo.exceptions import QWebException from odoo.tools.safe_eval import safe_eval -from odoo.addons.base import ir -from odoo.addons.website.models.website import slug, url_for, _UNSLUG_RE +from odoo.addons.http_routing.models.ir_http import ModelConverter +from odoo.addons.website.models.website import url_for logger = logging.getLogger(__name__) @@ -29,11 +28,6 @@ logger = logging.getLogger(__name__) odoo._geoip_resolver = None -class RequestUID(object): - def __init__(self, **kw): - self.__dict__.update(kw) - - class Http(models.AbstractModel): _inherit = 'ir.http' @@ -242,11 +236,6 @@ class Http(models.AbstractModel): def _postprocess_args(cls, arguments, rule): super(Http, cls)._postprocess_args(arguments, rule) - for key, val in pycompat.items(arguments): - # Replace uid placeholder by the current request.uid - if isinstance(val, models.BaseModel) and isinstance(val._uid, RequestUID): - arguments[key] = val.sudo(request.uid) - try: _, path = rule.build(arguments) assert path is not None @@ -341,26 +330,7 @@ class Http(models.AbstractModel): return super(Http, cls).binary_content(xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, download=download, mimetype=mimetype, default_mimetype=default_mimetype, env=env) -class ModelConverter(ir.ir_http.ModelConverter): - - def __init__(self, url_map, model=False, domain='[]'): - super(ModelConverter, self).__init__(url_map, model) - self.domain = domain - self.regex = _UNSLUG_RE.pattern - - def to_url(self, value): - return slug(value) - - def to_python(self, value): - matching = re.match(self.regex, value) - _uid = RequestUID(value=value, match=matching, converter=self) - record_id = int(matching.group(2)) - env = api.Environment(request.cr, _uid, request.context) - if record_id < 0: - # limited support for negative IDs due to our slug pattern, assume abs() if not found - if not env[self.model].browse(record_id).exists(): - record_id = abs(record_id) - return env[self.model].browse(record_id) +class ModelConverter(ModelConverter): def generate(self, uid, query=None, args=None): Model = request.env[self.model].sudo(uid) diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 034ace846c2..be56b6b806b 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -3,7 +3,6 @@ import logging from itertools import groupby -from lxml import etree from odoo import api, fields, models from odoo import tools @@ -117,21 +116,10 @@ class View(models.Model): if 'main_object' not in qcontext: qcontext['main_object'] = self - def unslug_url(s): - parts = s.split('/') - if parts: - unslug_val = website.unslug(parts[-1]) - if unslug_val[1]: - parts[-1] = str(unslug_val[1]) - return '/'.join(parts) - return s - qcontext.update(dict( self._context.copy(), website=request.website, url_for=website.url_for, - slug=website.slug, - unslug_url=unslug_url, res_company=request.website.company_id.sudo(), default_lang_code=request.website.default_lang_code, languages=request.website.get_languages(), diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 0b407e4d753..ba653a7a796 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -4,22 +4,15 @@ import inspect import logging import math -import unicodedata -import re import hashlib +import re from werkzeug import urls from werkzeug.exceptions import NotFound -# optional python-slugify import (https://github.com/un33k/python-slugify) -try: - import slugify as slugify_lib -except ImportError: - slugify_lib = None - -from odoo import api, fields, models -from odoo import tools -from odoo.tools import ustr, pycompat +from odoo import api, fields, models, tools +from odoo.addons.http_routing.models.ir_http import slugify +from odoo.tools import pycompat from odoo.http import request from odoo.tools.translate import _ @@ -91,62 +84,6 @@ def is_multilang_url(local_url, langs=None): return False -#################################################### -# Slug API -#################################################### - -def slugify(s, max_length=None): - """ Transform a string to a slug that can be used in a url path. - This method will first try to do the job with python-slugify if present. - Otherwise it will process string by stripping leading and ending spaces, - converting unicode chars to ascii, lowering all chars and replacing spaces - and underscore with hyphen "-". - :param s: str - :param max_length: int - :rtype: str - """ - s = ustr(s) - if slugify_lib: - # There are 2 different libraries only python-slugify is supported - try: - return slugify_lib.slugify(s, max_length=max_length) - except TypeError: - pass - uni = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore').decode('ascii') - slug_str = re.sub('[\W_]', ' ', uni).strip().lower() - slug_str = re.sub('[-\s]+', '-', slug_str) - - return slug_str[:max_length] - - -def slug(value): - if isinstance(value, models.BaseModel): - if isinstance(value.id, models.NewId): - raise ValueError("Cannot slug non-existent record %s" % value) - # [(id, name)] = value.name_get() - identifier, name = value.id, value.display_name - else: - # assume name_search result tuple - identifier, name = value - slugname = slugify(name or '').strip().strip('-') - if not slugname: - return str(identifier) - return "%s-%d" % (slugname, identifier) - -# NOTE: as the pattern is used as it for the ModelConverter (ir_http.py), do not use any flags -_UNSLUG_RE = re.compile(r'(?:(\w{1,2}|\w[A-Za-z0-9-_]+?\w)-)?(-?\d+)(?=$|/)') - - -def unslug(s): - """Extract slug and id from a string. - Always return un 2-tuple (str|None, int|None) - """ - m = _UNSLUG_RE.match(s) - if not m: - return None, None - return m.group(1), int(m.group(2)) - - class Website(models.Model): _name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco diff --git a/addons/website/tests/test_converter.py b/addons/website/tests/test_converter.py index 9267826c689..e5047971fa9 100644 --- a/addons/website/tests/test_converter.py +++ b/addons/website/tests/test_converter.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. import unittest -from odoo.addons.website.models.website import slugify, unslug +from odoo.addons.http_routing.models.ir_http import slugify, unslug from odoo.tools import pycompat diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index c400b8b792f..49ad2901ccc 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -9,8 +9,8 @@ import babel.dates from collections import OrderedDict from odoo import http, fields, _ +from odoo.addons.http_routing.models.ir_http import slug, unslug from odoo.addons.website.controllers.main import QueryURL -from odoo.addons.website.models.website import slug, unslug from odoo.exceptions import UserError from odoo.http import request from odoo.tools import html2plaintext diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 979ae14c5d3..f9df60422b2 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -7,7 +7,7 @@ import random import itertools from odoo import api, models, fields, _ -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug from odoo.tools.translate import html_translate from odoo.tools import html2plaintext diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py index 3c18c7cf470..9eb27180be9 100644 --- a/addons/website_crm_partner_assign/controllers/main.py +++ b/addons/website_crm_partner_assign/controllers/main.py @@ -10,7 +10,7 @@ from werkzeug.exceptions import NotFound from odoo import fields from odoo import http from odoo.http import request -from odoo.addons.website.models.website import slug, unslug +from odoo.addons.http_routing.models.ir_http import slug, unslug from odoo.addons.website_partner.controllers.main import WebsitePartnerPage from odoo.tools import pycompat diff --git a/addons/website_crm_partner_assign/models/res_partner.py b/addons/website_crm_partner_assign/models/res_partner.py index 40babddea73..aa0d40af98e 100644 --- a/addons/website_crm_partner_assign/models/res_partner.py +++ b/addons/website_crm_partner_assign/models/res_partner.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class ResPartnerGrade(models.Model): diff --git a/addons/website_customer/controllers/main.py b/addons/website_customer/controllers/main.py index e7318a64abf..480bb62c4d4 100644 --- a/addons/website_customer/controllers/main.py +++ b/addons/website_customer/controllers/main.py @@ -4,7 +4,7 @@ import werkzeug.urls from odoo import http -from odoo.addons.website.models.website import unslug +from odoo.addons.http_routing.models.ir_http import unslug from odoo.tools.translate import _ from odoo.http import request diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index 00e51627c0c..c9fc377161f 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -7,7 +7,7 @@ from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta from odoo import fields, http, _ -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug from odoo.http import request from odoo.tools import pycompat diff --git a/addons/website_event/models/event.py b/addons/website_event/models/event.py index 81ec8c79629..a5e70798b8c 100644 --- a/addons/website_event/models/event.py +++ b/addons/website_event/models/event.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- -import re - from odoo import api, fields, models, _ -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class EventType(models.Model): diff --git a/addons/website_event_track/models/event.py b/addons/website_event_track/models/event.py index baae681bc7b..92a096e42c1 100644 --- a/addons/website_event_track/models/event.py +++ b/addons/website_event_track/models/event.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models, _ -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class EventType(models.Model): diff --git a/addons/website_event_track/models/event_track.py b/addons/website_event_track/models/event_track.py index 5137fb0671f..6d3bf123ed0 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -3,7 +3,7 @@ from odoo import api, fields, models from odoo.tools.translate import _, html_translate -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class TrackTag(models.Model): diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index 703cf517374..6ee21087d80 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -11,8 +11,8 @@ import werkzeug.wrappers from datetime import datetime from odoo import http, modules, SUPERUSER_ID, tools, _ +from odoo.addons.http_routing.models.ir_http import slug from odoo.addons.web.controllers.main import binary_content -from odoo.addons.website.models.website import slug from odoo.http import request diff --git a/addons/website_hr_recruitment/controllers/main.py b/addons/website_hr_recruitment/controllers/main.py index 2ed3eafc2f6..e1faf43fdc7 100644 --- a/addons/website_hr_recruitment/controllers/main.py +++ b/addons/website_hr_recruitment/controllers/main.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import http, _ -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug from odoo.http import request diff --git a/addons/website_hr_recruitment/models/hr_recruitment.py b/addons/website_hr_recruitment/models/hr_recruitment.py index 7810ae2fccd..7d6e88c31c8 100644 --- a/addons/website_hr_recruitment/models/hr_recruitment.py +++ b/addons/website_hr_recruitment/models/hr_recruitment.py @@ -4,7 +4,6 @@ from werkzeug import urls from odoo import api, fields, models -from odoo.addons.website.models.website import slug from odoo.tools.translate import html_translate diff --git a/addons/website_livechat/models/im_livechat.py b/addons/website_livechat/models/im_livechat.py index 17ad3f89a12..6dc57e0845b 100644 --- a/addons/website_livechat/models/im_livechat.py +++ b/addons/website_livechat/models/im_livechat.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, models, fields -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug from odoo.tools.translate import html_translate diff --git a/addons/website_mail_channel/controllers/main.py b/addons/website_mail_channel/controllers/main.py index c9b3deb268e..e14f355f9f4 100644 --- a/addons/website_mail_channel/controllers/main.py +++ b/addons/website_mail_channel/controllers/main.py @@ -8,7 +8,8 @@ from dateutil import relativedelta from odoo import http, fields, tools from odoo.http import request -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug + class MailGroup(http.Controller): _thread_per_page = 20 diff --git a/addons/website_mail_channel/models/mail_channel.py b/addons/website_mail_channel/models/mail_channel.py index 519dfe7afc6..c8ef8f3414c 100644 --- a/addons/website_mail_channel/models/mail_channel.py +++ b/addons/website_mail_channel/models/mail_channel.py @@ -7,7 +7,7 @@ from werkzeug import urls from odoo import api, models from odoo.tools.safe_eval import safe_eval -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class MailGroup(models.Model): diff --git a/addons/website_mail_channel/models/mail_mail.py b/addons/website_mail_channel/models/mail_mail.py index 4257c828b66..fd7d0f1fb3e 100644 --- a/addons/website_mail_channel/models/mail_mail.py +++ b/addons/website_mail_channel/models/mail_mail.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, models, tools, _ -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class MailMail(models.Model): diff --git a/addons/website_membership/controllers/main.py b/addons/website_membership/controllers/main.py index 3097ac0437c..42dcf599220 100644 --- a/addons/website_membership/controllers/main.py +++ b/addons/website_membership/controllers/main.py @@ -7,7 +7,7 @@ from odoo import fields from odoo import http from odoo.http import request -from odoo.addons.website.models.website import unslug +from odoo.addons.http_routing.models.ir_http import unslug from odoo.tools.translate import _ diff --git a/addons/website_partner/controllers/main.py b/addons/website_partner/controllers/main.py index 1cc4fce906f..c8cac98d969 100644 --- a/addons/website_partner/controllers/main.py +++ b/addons/website_partner/controllers/main.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from odoo import http +from odoo.addons.http_routing.models.ir_http import unslug from odoo.http import request -from odoo.addons.website.models.website import unslug class WebsitePartnerPage(http.Controller): diff --git a/addons/website_partner/models/res_partner.py b/addons/website_partner/models/res_partner.py index 2587472a026..c11922a5833 100644 --- a/addons/website_partner/models/res_partner.py +++ b/addons/website_partner/models/res_partner.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from odoo import api, fields, models -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug class WebsiteResPartner(models.Model): diff --git a/addons/website_project/models/project.py b/addons/website_project/models/project.py index e55a1d88d67..4c91abe1b7a 100644 --- a/addons/website_project/models/project.py +++ b/addons/website_project/models/project.py @@ -2,7 +2,6 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, exceptions, models, fields -from odoo.addons.website.models.website import slug class Project(models.Model): diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 17d46d1a7ba..5d0972461a1 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -7,7 +7,7 @@ from werkzeug.exceptions import Forbidden from odoo import http, tools, _ from odoo.http import request from odoo.addons.base.ir.ir_qweb.fields import nl2br -from odoo.addons.website.models.website import slug +from odoo.addons.http_routing.models.ir_http import slug from odoo.addons.website.controllers.main import QueryURL from odoo.exceptions import ValidationError from odoo.addons.website_form.controllers.main import WebsiteForm diff --git a/addons/website_slides/models/slides.py b/addons/website_slides/models/slides.py index ee65b15734b..01a0fda6dc2 100644 --- a/addons/website_slides/models/slides.py +++ b/addons/website_slides/models/slides.py @@ -11,10 +11,10 @@ import re from werkzeug import urls from odoo import api, fields, models, SUPERUSER_ID, _ +from odoo.addons.http_routing.models.ir_http import slug from odoo.tools import image, pycompat from odoo.tools.translate import html_translate from odoo.exceptions import Warning -from odoo.addons.website.models.website import slug class Channel(models.Model): diff --git a/odoo/addons/base/ir/ir_http.py b/odoo/addons/base/ir/ir_http.py index 0aa1abc52ca..32738298293 100644 --- a/odoo/addons/base/ir/ir_http.py +++ b/odoo/addons/base/ir/ir_http.py @@ -10,6 +10,7 @@ import mimetypes import os import re import sys +import unicodedata import werkzeug import werkzeug.exceptions @@ -27,7 +28,10 @@ from odoo.modules.module import get_resource_path, get_module_path _logger = logging.getLogger(__name__) -UID_PLACEHOLDER = object() + +class RequestUID(object): + def __init__(self, **kw): + self.__dict__.update(kw) class ModelConverter(werkzeug.routing.BaseConverter): @@ -38,7 +42,8 @@ class ModelConverter(werkzeug.routing.BaseConverter): self.regex = r'([0-9]+)' def to_python(self, value): - env = api.Environment(request.cr, UID_PLACEHOLDER, request.context) + _uid = RequestUID(value=value, converter=self) + env = api.Environment(request.cr, _uid, request.context) return env[self.model].browse(int(value)) def to_url(self, value): @@ -54,7 +59,8 @@ class ModelsConverter(werkzeug.routing.BaseConverter): self.regex = r'([0-9,]+)' def to_python(self, value): - env = api.Environment(request.cr, UID_PLACEHOLDER, request.context) + _uid = RequestUID(value=value, converter=self) + env = api.Environment(request.cr, _uid, request.context) return env[self.model].browse(int(v) for v in value.split(',')) def to_url(self, value): @@ -203,10 +209,11 @@ class IrHttp(models.AbstractModel): @classmethod def _postprocess_args(cls, arguments, rule): """ post process arg to set uid on browse records """ - for name, arg in list(pycompat.items(arguments)): - if isinstance(arg, models.BaseModel) and arg._uid is UID_PLACEHOLDER: - arguments[name] = arg.sudo(request.uid) - if not arg.exists(): + for key, val in list(pycompat.items(arguments)): + # Replace uid placeholder by the current request.uid + if isinstance(val, models.BaseModel) and isinstance(val._uid, RequestUID): + arguments[key] = val.sudo(request.uid) + if not val.exists(): return cls._handle_exception(werkzeug.exceptions.NotFound()) @classmethod |
