[IMP] model converters for routes, to directly get the browse record
authorAntony Lesuisse <al@openerp.com>
Sun, 10 Nov 2013 12:37:07 +0000 (13:37 +0100)
committerAntony Lesuisse <al@openerp.com>
Sun, 10 Nov 2013 12:37:07 +0000 (13:37 +0100)
example @route(['/job/detail/<model("hr.job"):job>'], type='http', auth="user")

bzr revid: al@openerp.com-20131110123707-yb3hbdqlo063dj64

openerp/addons/base/ir/ir_http.py
openerp/http.py

index 4b54a49..995ed33 100644 (file)
@@ -13,6 +13,43 @@ from openerp.osv import osv
 
 _logger = logging.getLogger(__name__)
 
+class RequestUID(object):
+    pass
+
+class ModelConverter(werkzeug.routing.BaseConverter):
+
+    def __init__(self, url_map, model=False):
+        super(ModelConverter, self).__init__(url_map)
+        self.model = model
+        # TODO add support for slug in the form [A-Za-z0-9-] bla-bla-89 -> id 89
+        self.regex = '([0-9]+)'
+
+    def to_python(self, value):
+        # TODO:
+        # - raise routing.ValidationError() if no browse record can be createdm
+        # - support slug 
+        return request.registry[self.model].browse(request.cr, RequestUID(), int(value), context=request.context)
+
+    def to_url(self, value):
+        return value.id
+
+class ModelsConverter(werkzeug.routing.BaseConverter):
+
+    def __init__(self, url_map, model=False):
+        super(ModelsConverter, self).__init__(url_map)
+        self.model = model
+        # TODO add support for slug in the form [A-Za-z0-9-] bla-bla-89 -> id 89
+        self.regex = '([0-9,]+)'
+
+    def to_python(self, value):
+        # TODO:
+        # - raise routing.ValidationError() if no browse record can be createdm
+        # - support slug
+        return request.registry[self.model].browse(request.cr, RequestUID(), [int(i) for i in value.split(',')], context=request.context)
+
+    def to_url(self, value):
+        return ",".join([i.id for i in value])
+
 class ir_http(osv.osv):
     _name = 'ir.http'
     _description = "HTTP routing"
@@ -29,7 +66,7 @@ class ir_http(osv.osv):
             ids = m.search(cr, openerp.SUPERUSER_ID, [('state', '=', 'installed'), ('name', '!=', 'web')])
             installed = set(x['name'] for x in m.read(cr, 1, ids, ['name']))
             mods = ['', "web"] + sorted(installed)
-            self.routing_map = http.routing_map(mods, False)
+            self.routing_map = http.routing_map(mods, False, converters={'model': ModelConverter, 'models': ModelsConverter})
 
         # fallback to non-db handlers
         path = request.httprequest.path
@@ -84,6 +121,11 @@ class ir_http(osv.osv):
         except werkzeug.exceptions.NotFound, e:
             return self._handle_403(e)
 
+        # post process arg to set uid on browse records
+        for arg in arguments:
+            if isinstance(arg, openerp.osv.orm.browse_record) and isinstance(arg._uid, RequestUID):
+                arg._uid = request.uid
+
         # set and execute handler
         try:
             request.set_handler(func, arguments, auth_method)
index 2425552..98107cd 100644 (file)
@@ -495,8 +495,8 @@ class ControllerType(type):
 class Controller(object):
     __metaclass__ = ControllerType
 
-def routing_map(modules, nodb_only):
-    routing_map = werkzeug.routing.Map(strict_slashes=False)
+def routing_map(modules, nodb_only, converters=None):
+    routing_map = werkzeug.routing.Map(strict_slashes=False, converters=converters)
     for module in modules:
         if module not in controllers_per_module:
             continue