[FIX] ir_model: field names must be valid pg identifiers
This commit is contained in:
committed by
Raphael Collet
parent
e79d94438e
commit
6b48098c81
@@ -7370,6 +7370,12 @@ msgstr ""
|
||||
msgid "Field `%(field_name)s` does not exist"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_model.py:298
|
||||
#, python-format
|
||||
msgid "Field names can only contain characters, digits and underscores (up to 63)."
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_model_fields
|
||||
#: model:ir.model,name:base.model_ir_model_fields
|
||||
|
||||
@@ -286,6 +286,17 @@ class IrModelFields(models.Model):
|
||||
raise UserError(_("The Selection Options expression is not a valid Pythonic expression."
|
||||
"Please provide an expression in the [('key','Label'), ...] format."))
|
||||
|
||||
@api.constrains('name', 'state')
|
||||
def _check_name(self):
|
||||
for field in self:
|
||||
if field.state == 'manual' and not field.name.startswith('x_'):
|
||||
raise ValidationError(_("Custom fields must have a name that starts with 'x_' !"))
|
||||
try:
|
||||
models.check_pg_name(field.name)
|
||||
except ValidationError:
|
||||
msg = _("Field names can only contain characters, digits and underscores (up to 63).")
|
||||
raise ValidationError(msg)
|
||||
|
||||
_sql_constraints = [
|
||||
('size_gt_zero', 'CHECK (size>=0)', 'Size of the field cannot be negative.'),
|
||||
]
|
||||
@@ -492,9 +503,6 @@ class IrModelFields(models.Model):
|
||||
res = super(IrModelFields, self).create(vals)
|
||||
|
||||
if vals.get('state', 'manual') == 'manual':
|
||||
if not vals['name'].startswith('x_'):
|
||||
raise UserError(_("Custom fields must have a name that starts with 'x_' !"))
|
||||
|
||||
if vals.get('relation') and not self.env['ir.model'].search([('model', '=', vals['relation'])]):
|
||||
raise UserError(_("Model %s does not exist!") % vals['relation'])
|
||||
|
||||
@@ -559,10 +567,6 @@ class IrModelFields(models.Model):
|
||||
raise UserError(_('Can only rename one field at a time!'))
|
||||
if vals['name'] in obj._fields:
|
||||
raise UserError(_('Cannot rename field to %s, because that field already exists!') % vals['name'])
|
||||
if vals.get('state', 'manual') == 'manual' and not vals['name'].startswith('x_'):
|
||||
raise UserError(_('New field name must still start with x_ , because it is a custom field!'))
|
||||
if '\'' in vals['name'] or '"' in vals['name'] or ';' in vals['name']:
|
||||
raise ValueError('Invalid character in column name')
|
||||
column_rename = (obj._table, item.name, vals['name'], item.index)
|
||||
|
||||
# We don't check the 'state', because it might come from the context
|
||||
|
||||
@@ -368,3 +368,58 @@ class TestServerActions(TestServerActionsBase):
|
||||
self.action.write({
|
||||
'child_ids': [(6, 0, [self.action.id])]
|
||||
})
|
||||
|
||||
|
||||
class TestCustomFields(common.TransactionCase):
|
||||
MODEL = 'res.partner'
|
||||
|
||||
def setUp(self):
|
||||
# use a test cursor instead of a real cursor
|
||||
registry = odoo.registry()
|
||||
registry.enter_test_mode()
|
||||
fnames = set(registry[self.MODEL]._fields)
|
||||
|
||||
@self.addCleanup
|
||||
def callback():
|
||||
registry.leave_test_mode()
|
||||
# the tests may have modified the registry, reset it
|
||||
with registry.cursor() as cr:
|
||||
registry.clear_manual_fields()
|
||||
registry.setup_models(cr)
|
||||
assert set(registry[self.MODEL]._fields) == fnames
|
||||
|
||||
super(TestCustomFields, self).setUp()
|
||||
|
||||
def create_field(self, name):
|
||||
""" create a custom field and return it """
|
||||
model = self.env['ir.model'].search([('model', '=', self.MODEL)])
|
||||
field = self.env['ir.model.fields'].create({
|
||||
'model_id': model.id,
|
||||
'name': name,
|
||||
'field_description': name,
|
||||
'ttype': 'char',
|
||||
})
|
||||
self.assertIn(name, self.env[self.MODEL]._fields)
|
||||
return field
|
||||
|
||||
def test_create_custom(self):
|
||||
""" custom field names must be start with 'x_' """
|
||||
with self.assertRaises(ValidationError):
|
||||
self.create_field('foo')
|
||||
|
||||
def test_rename_custom(self):
|
||||
""" custom field names must be start with 'x_' """
|
||||
field = self.create_field('x_foo')
|
||||
with self.assertRaises(ValidationError):
|
||||
field.name = 'foo'
|
||||
|
||||
def test_create_valid(self):
|
||||
""" field names must be valid pg identifiers """
|
||||
with self.assertRaises(ValidationError):
|
||||
self.create_field('x_foo bar')
|
||||
|
||||
def test_rename_valid(self):
|
||||
""" field names must be valid pg identifiers """
|
||||
field = self.create_field('x_foo')
|
||||
with self.assertRaises(ValidationError):
|
||||
field.name = 'x_foo bar'
|
||||
|
||||
Reference in New Issue
Block a user