Skip to Content

Contributors

A methodology / best practice / Odoo / Python question

Hello,

 

I am struggling with this for a while so I have decided to ask here. I am building a module that would be showing active filters/ordering as tags on e-commerce by parsing query part of the URL. Besides the standard ones (search, order) we are also using brands filter and also custom_info. Both of these can have multiple options checked. User has the option to remove them individually instead of searching for appropriate checkobxes on the page. Now my approach is basically iterate through key/value pairs and for each generate what looks like a tag visually with URL that has that key/value pair removed (so it in fact removes that part of filter). For that I have devised a code like this:

 

from odoo.http import request

 

from werkzeug import OrderedMultiDict

from werkzeug.urls import url_parse, url_encode

 

def _get_filtered_url(param, value):

filtered_args = OrderedMultiDict(filter(lambda arg: arg[0]!=param or arg[1]!=value, request.httprequest.args.items(multi=True)))

url = url_parse(request.httprequest.url)

return url.replace(query=url_encode(filtered_args)).to_url()

 

Now this code is obviously not a object/class method - it should be (in my opinion) a static method. Now the question is: static method of what? Because I need to be able to call it from XML template that renders part of WebsiteSale. I guess I could create a dummy (transient?) class and call it like request.env['my_transient_class']._get_filtered_url(param, value) but that somehow does not seem right to me. Or is it the right way? I am trying to write a clean concise code that is not hacky.

 

Any advice is welcome here. Thank you very much.

 

Best regards

 

Radovan Skolnik

 


by Radovan Skolnik - 10:25 - 6 Sep 2021

Follow-Ups

  • Re: A methodology / best practice / Odoo / Python question
    Simone!
    
    Thanx a lot! That's exactly what I was looking for. Seems so straightforward 
    now.
    
    Best regards
    
    	Radovan
    
    On utorok 7. septembra 2021 10:32:07 CEST Simone Rubino wrote:
    
    > Hi, you can also use functions to render QWeb templates, so you can declare
    
    > the function in any Python file and add it to the values used to render the
    
    > pages that will need your function. For instance, see how `format_date` is
    
    > used in 
    
    > https://github.com/odoo/odoo/blob/070bec2f3a7a50c6fc8f104cf92a9416ebc001b8/
    
    > addons/mail/models/mail_render_mixin.py#L244 [1]  for rendering e-mails. To
    
    > add your function to the values of any website page you can override
    
    > `_prepare_qcontext` (
    
    > https://github.com/odoo/odoo/blob/3f96cff0aa5097a386c289cf9fd2aeb3048376ab/
    
    > odoo/addons/base/models/ir_ui_view.py#L1720 [2] ) or you can add it
    
    > individually to the values of the page that need your function. On Mon, 6
    
    > Sept 2021 at 10:26, Radovan Skolnik < radovan@skolnik.info [3] > wrote:
    
    > Hello,
    
    > 
    
    > I am struggling with this for a while so I have decided to ask here. I am
    
    > building a module that would be showing active filters/ordering as tags on
    
    > e-commerce by parsing query part of the URL. Besides the standard ones
    
    > (search, order) we are also using brands filter and also custom_info. Both
    
    > of these can have multiple options checked. User has the option to remove
    
    > them individually instead of searching for appropriate checkobxes on the
    
    > page. Now my approach is basically iterate through key/value pairs and for
    
    > each generate what looks like a tag visually with URL that has that
    
    > key/value pair removed (so it in fact removes that part of filter). For
    
    > that I have devised a code like this:
    
    > 
    
    > from odoo.http import request
    
    > 
    
    > from werkzeug import OrderedMultiDict
    
    > from werkzeug.urls import url_parse, url_encode
    
    > 
    
    > def _get_filtered_url(param, value):
    
    > filtered_args = OrderedMultiDict(filter(lambda arg: arg[0]!=param or
    
    > arg[1]!=value, request.httprequest.args.items(multi=True))) url =
    
    > url_parse(request.httprequest.url)
    
    > return url.replace(query=url_encode(filtered_args)).to_url()
    
    > 
    
    > Now this code is obviously not a object/class method - it should be (in my
    
    > opinion) a static method. Now the question is: static method of what?
    
    > Because I need to be able to call it from XML template that renders part of
    
    > WebsiteSale. I guess I could create a dummy (transient?) class and call it
    
    > like request.env['my_transient_class']._get_filtered_url(param, value) but
    
    > that somehow does not seem right to me. Or is it the right way? I am trying
    
    > to write a clean concise code that is not hacky.
    
    > 
    
    > Any advice is welcome here. Thank you very much.
    
    > 
    
    > Best regards
    
    > 
    
    > Radovan Skolnik
    
    > 
    
    > _______________________________________________
    
    > Mailing-List: https://odoo-community.org/groups/contributors-15 [4]
    
    > Post to: mailto: contributors@odoo-community.org [5]
    
    > Unsubscribe: https://odoo-community.org/groups?unsubscribe [6]
    
    > 
    
    > 
    
    > _______________________________________________
    
    > Mailing-List: https://odoo-community.org/groups/contributors-15 [7]
    
    > Post to: mailto:contributors@odoo-community.org
    
    > Unsubscribe: https://odoo-community.org/groups?unsubscribe [8]
    
    > 
    
    > 
    
    > 
    
    > [1]
    
    > https://github.com/odoo/odoo/blob/070bec2f3a7a50c6fc8f104cf92a9416ebc001b8/
    
    > addons/mail/models/mail_render_mixin.py#L244 [2]
    
    > https://github.com/odoo/odoo/blob/3f96cff0aa5097a386c289cf9fd2aeb3048376ab/
    
    > odoo/addons/base/models/ir_ui_view.py#L1720 [3] mailto:radovan@skolnik.info
    
    > [4] https://odoo-community.org/groups/contributors-15
    
    > [5] mailto:contributors@odoo-community.org
    
    > [6] https://odoo-community.org/groups?unsubscribe
    
    > [7] https://odoo-community.org/groups/contributors-15
    
    > [8] https://odoo-community.org/groups?unsubscribe
    
    
    
    
    

    by Radovan Skolnik - 01:40 - 7 Sep 2021
  • Re: A methodology / best practice / Odoo / Python question
    Hi,
    you can also use functions to render QWeb templates, so you can declare the function in any Python file and add it to the values used to render the pages that will need your function.

    To add your function to the values of any website page you can override `_prepare_qcontext` (https://github.com/odoo/odoo/blob/3f96cff0aa5097a386c289cf9fd2aeb3048376ab/odoo/addons/base/models/ir_ui_view.py#L1720) or you can add it individually to the values of the page that need your function.


    On Mon, 6 Sept 2021 at 10:26, Radovan Skolnik <radovan@skolnik.info> wrote:

    Hello,

     

    I am struggling with this for a while so I have decided to ask here. I am building a module that would be showing active filters/ordering as tags on e-commerce by parsing query part of the URL. Besides the standard ones (search, order) we are also using brands filter and also custom_info. Both of these can have multiple options checked. User has the option to remove them individually instead of searching for appropriate checkobxes on the page. Now my approach is basically iterate through key/value pairs and for each generate what looks like a tag visually with URL that has that key/value pair removed (so it in fact removes that part of filter). For that I have devised a code like this:

     

    from odoo.http import request

     

    from werkzeug import OrderedMultiDict

    from werkzeug.urls import url_parse, url_encode

     

    def _get_filtered_url(param, value):

    filtered_args = OrderedMultiDict(filter(lambda arg: arg[0]!=param or arg[1]!=value, request.httprequest.args.items(multi=True)))

    url = url_parse(request.httprequest.url)

    return url.replace(query=url_encode(filtered_args)).to_url()

     

    Now this code is obviously not a object/class method - it should be (in my opinion) a static method. Now the question is: static method of what? Because I need to be able to call it from XML template that renders part of WebsiteSale. I guess I could create a dummy (transient?) class and call it like request.env['my_transient_class']._get_filtered_url(param, value) but that somehow does not seem right to me. Or is it the right way? I am trying to write a clean concise code that is not hacky.

     

    Any advice is welcome here. Thank you very much.

     

    Best regards

     

    Radovan Skolnik

     

    _______________________________________________
    Mailing-List: https://odoo-community.org/groups/contributors-15
    Post to: mailto:contributors@odoo-community.org
    Unsubscribe: https://odoo-community.org/groups?unsubscribe


    by Simone Rubino - 10:31 - 7 Sep 2021