-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX] validate field names in attributes of views #20893
Conversation
@sle-odoo I had to fix some views in mrp and stock. |
bc52496
to
65d6f9e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not confident enough with my Python knowledge to approve but that's a great improvement ! Thanks.
@@ -121,7 +121,7 @@ | |||
<field name="needs_lots" readonly="1" groups="stock.group_production_lot"/> | |||
<field name="is_done" invisible="1"/> | |||
<field name="sequence" invisible="1"/> | |||
<field name="location_id" domain="[('id', 'child_of', parent.location_id)]" invisible="1"/> | |||
<field name="location_id" invisible="1"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you can just delete the domain? Maybe the field has been renamed? I see production_location_id
on the parent, could it be it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are 3 fields referring to locations in the parent model...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't care since it's invisible
@@ -79,7 +79,7 @@ | |||
<span><field name="product_uom_qty" readonly="1" nolabel="1"/></span> | |||
<span><field name="product_uom_id" attrs="{'readonly': [('id', '!=', False)]}" nolabel="1"/></span> | |||
</div> | |||
<field name="lot_id" string="Lot/Serial number" groups="stock.group_production_lot" readonly="1" attrs="{'invisible': [('lots_visible', '=', False)]}"/> | |||
<field name="lot_id" string="Lot/Serial number" groups="stock.group_production_lot" readonly="1"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lots_visible
still exists on the model ; invisible isn't needed anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the field lots_visible as invisible instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the attrs
keeps the behavior as is. We can also add the field lots_visible
in the view...
odoo/addons/base/tests/test_views.py
Outdated
}) | ||
|
||
@mute_logger('odoo.addons.base.ir.ir_ui_view') | ||
def test_context_in_subview(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have added a test if model is not in the subview but in the main view.
odoo/addons/base/tests/test_views.py
Outdated
</form> | ||
""", | ||
}) | ||
with self.assertRaises(ValidationError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idem (error if model in main view but not in subview).
65d6f9e
to
56cbaaa
Compare
56cbaaa
to
b2ddd22
Compare
@@ -9,7 +9,7 @@ | |||
<field name="product_id"/> | |||
<field name="product_uom_qty"/> | |||
<field name="product_uom" options="{'no_open': True, 'no_create': True}" string="Unit of Measure" groups="product.group_uom"/> | |||
<field name="product_packaging" domain="[('product_tmpl_id','=',product_tmpl_id)]" groups="product.group_stock_packaging"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should replace it by domain="[('product_id','=',product_id)]" instead of remove it
@@ -183,7 +183,7 @@ | |||
<tree editable="bottom" decoration-muted="state == 'done' and is_locked == True" decoration-success="product_uom_qty==qty_done" decoration-danger="qty_done > product_uom_qty and state != 'done'"> | |||
<field name="picking_id" invisible="1"/> | |||
<field name="product_id" invisible="1"/> | |||
<field name="location_id" invisible="not context.get('show_source_location')" domain="[('id', 'child_of', parent.location_id)])" groups="stock.group_stock_multi_locations"/> | |||
<field name="location_id" invisible="not context.get('show_source_location')" groups="stock.group_stock_multi_locations"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should we do? Do we need to duplicate twice this view and add them in two inline views instead of using tree_view_ref? Or create a related field parent_location_id on stock_move_line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@amoyaux We can also add the missing field location_id
in the parent view(s).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually this domain had a typo (extra closing parenthesis).
So I just fixed the typo 😄
76a2c9c
to
6d7a408
Compare
please my friends, do not even think put this in master PLEASE ;-) |
@nhomar why? Can you elaborate on this? The main purpose of this validation is to prevent people from screwing up views with Studio. We recently got examples of users removing fields from views, and making domains impossible to evaluate. The issue was totally invisible while in Studio, but the view kept on crashing when used for real |
6d7a408
to
73bab27
Compare
@rco-odoo I mean I love it in 11.0 as it is, but the point is that the stable policy does not allow fix this kind of big things in stable and this PR is very nice, this was the reason of my comments. |
odoo/addons/base/ir/ir_ui_view.py
Outdated
# retrieve subfields of 'parent' | ||
get = partial(get_parent, get) | ||
for child in node: | ||
yield from node_names(child, get) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That doesn't seem like a hill worth removing Python 2 support on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not funny. I wanted to break some stuff ;-)
odoo/addons/base/ir/ir_ui_view.py
Outdated
return ['self', 'parent', 'id', 'uid', 'context', | ||
'active_id', 'active_ids', 'active_model', | ||
'time', 'datetime', 'relativedelta', | ||
'context_today', 'current_date'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could return a set directly.
odoo/addons/base/ir/ir_ui_view.py
Outdated
return (name | ||
for node in ast.walk(ast.parse(expr.strip(), mode='eval')) | ||
for name in [get(node)] | ||
if name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why make these inner functions? That seems unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Readability. It took me a while to get the algorithm right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand having them as functions (that seems fair), just not inner ones, why not toplevel?
odoo/addons/base/ir/ir_ui_view.py
Outdated
attrs = node.get('attrs') | ||
# collect field names in left-hand-side of conditions | ||
for domain in safe_eval(attrs).values(): | ||
if isinstance(domain, list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any case where the domain could be a non-list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It once crashed with a boolean domain. Maybe we should fix the domain...
@nhomar I understand and I always keep this aspect in mind. I was thinking about using this when actually validating the view, but not when building the view for the client (via |
@rco-odoo |
50f5217
to
c4566f4
Compare
50537cc
to
3ac561a
Compare
@mart-e I add a new translated term here (error message). |
@odony this adds some extra validation in views, to answer a request from the Studio team. I would very much appreciate your review. Implementing the validation brought a few surprises: some views in Odoo 11 are not valid. Hopefully they do not seem to break anything so far, because of domains never being evaluated or so. |
ping @odony |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good and elegant, considering the complexity of the verification, thanks!
It will be excellent with the small improvement to the error message, as discussed.
3ac561a
to
a3f3d9c
Compare
a3f3d9c
to
0109c9e
Compare
OPW 779494