[英]Odoo 15 "required field is not set" eventhough it is clearly selected
I have created a video to demonstrate the video: https://vimeo.com/748701130我创建了一个视频来演示视频: https://vimeo.com/748701130
When I click on save in the event.booth model that is open, I get the error message that event.event has not been selected but it is a required field.当我单击打开的 event.booth model 中的保存时,我收到错误消息 event.event 尚未被选择,但它是必填字段。 This is however not true, as visible in the video.
然而,这不是真的,如视频中所示。 The field is clearly selected.
该字段已明确选择。
This is the code for the model: (I am inheriting event.booth)这是 model 的代码:(我继承了 event.booth)
# -*- coding: utf-8 -*-
from odoo import models, fields, api
from . import prepare_engine as rectanglemaps_engine
class EventBooth(models.Model):
_inherit = 'event.booth'
name = fields.Char(string='Name', compute='_compute_name')
display_name = fields.Char(string="Anzeigename", compute='_compute_display_name', inverse='_inverse_display_name', store=True)
# Verbundene Halle
halle_id = fields.Many2one('rectanglemaps.halle', string='Halle')
# Allgemein
start_number = fields.Float(string="Von", default=0, required=True)
front = fields.Float(string="Front", default=4, required=True)
end_number = fields.Float(string="Bis", compute='_compute_end_number', inverse='_inverse_end_number', store=True)
area = fields.Float(string="Fläche", compute='_compute_area', store=True)
depth = fields.Float(string="Standtiefe", compute='_compute_depth', inverse='_inverse_depth', store=True)
# Planattribute
draw = fields.Boolean(string="Einzeichnen", default=True)
stand_inset = fields.Float(string="Stand Einsatz", default=0)
walls = fields.Selection([('b', 'Braun'), ('w', 'Weiß')], string="Wände")
# carpet = fields.Selection([('1', 'orange'), ('2', 'grün'), ('3', 'grau'), ('4', 'blau')], string="Teppich")
carpet = fields.Many2one('rectanglemaps.carpet', string='Teppich')
# Planattribute - Wände
available_walls = [('b', 'Braun'), ('w', 'Weiß')]
# upper wall
wall_1_draw = fields.Boolean(string="Obere Wand", compute='_compute_wall_1_draw', inverse='_inverse_wall', store=True)
wall_1_start = fields.Float(string="Einsatz links")
wall_1_end = fields.Float(string="Einsatz rechts")
wall_1_color = fields.Selection(available_walls, string="Wandtyp", default='w')
# rightmost wall
wall_2_draw = fields.Boolean(string="Rechte Wand", compute='_compute_wall_2_draw', inverse='_inverse_wall', store=True)
wall_2_start = fields.Float(string="Einsatz oben")
wall_2_end = fields.Float(string="Einsatz unten")
wall_2_color = fields.Selection(available_walls, string="Wandtyp", default='w')
# lower wall
wall_3_draw = fields.Boolean(string="Untere Wand", compute='_compute_wall_3_draw', inverse='_inverse_wall', store=True)
wall_3_start = fields.Float(string="Einsatz links")
wall_3_end = fields.Float(string="Einsatz rechts")
wall_3_color = fields.Selection(available_walls, string="Wandtyp", default='w')
# leftmost wall
wall_4_draw = fields.Boolean(string="Linke Wand", compute='_compute_wall_4_draw', inverse='_inverse_wall', store=True)
wall_4_start = fields.Float(string="Einsatz oben")
wall_4_end = fields.Float(string="Einsatz unten")
wall_4_color = fields.Selection(available_walls, string="Wandtyp", default='w')
# Standvorschau
preview = fields.Image(string="Vorschau")
@api.depends('halle_id.name', 'start_number', 'front')
def _compute_name(self):
for record in self:
try:
sn = record.start_number
if (record.start_number).is_integer():
sn = int(record.start_number)
en = record.start_number + record.front
if (en).is_integer():
en = int(en)
record.name = record.halle_id.name + ' | ' + str(sn) + ' - ' + str(en)
except:
record.name = 'Stand'
@api.depends('start_number', 'front')
def _compute_end_number(self):
for record in self:
record.end_number = record.start_number + record.front
def _inverse_end_number(self):
for record in self:
record.front = record.end_number - record.start_number
@api.depends('start_number', 'end_number', 'depth')
def _compute_area(self):
for record in self:
record.area = (record.end_number - record.start_number) * record.depth
@api.depends('partner_id.name')
def _compute_display_name(self):
for record in self:
record.display_name = record.partner_id.name
@api.depends('start_number')
def _compute_depth(self):
for record in self:
if record.start_number < 200:
record.depth = record.halle_id.stand_s
elif record.start_number < 400:
record.depth = record.halle_id.stand_e
elif record.start_number < 600:
record.depth = record.halle_id.stand_n
elif record.start_number < 800:
record.depth = record.halle_id.stand_w
@api.depends()
def _inverse_depth(self):
for record in self:
pass
@api.depends()
def _inverse_display_name(self):
for record in self:
pass
@api.depends('start_number')
def _compute_wall_1_draw(self):
for record in self:
record.wall_1_draw = 200 < record.start_number < 1000
@api.depends('start_number')
def _compute_wall_2_draw(self):
for record in self:
record.wall_2_draw = record.start_number < 600 or 800 < record.start_number < 1000
@api.depends('start_number')
def _compute_wall_3_draw(self):
for record in self:
record.wall_3_draw = record.start_number < 400 or 600 < record.start_number < 1000
@api.depends('start_number')
def _compute_wall_4_draw(self):
for record in self:
record.wall_4_draw = record.start_number < 200 or 400 < record.start_number < 1000
def _inverse_wall(self):
for record in self:
pass
# used in view
def action_confirm_stand(self):
self.state = 'done'
# used in view
def action_cancel_stand(self):
self.state = 'cancelled'
def action_plan_redraw(self):
self.draw_preview()
def draw_preview(self):
self.preview = rectanglemaps_engine.prepare_engine_stand(self)
# used in view
def action_create_offer(self):
print("Create offer")
@api.model
def create(self, values):
if self.halle_id != False:
values['event_id'] = self.halle_id.event_id.id
return super(EventBooth, self).create(values)
@api.onchange('name', 'start_number', 'end_number', 'depth', 'wall_1_draw', 'wall_1_start', 'wall_1_end', 'wall_2_draw', 'wall_2_start', 'wall_2_end', 'wall_3_draw', 'wall_3_start', 'wall_3_end', 'wall_4_draw', 'wall_4_start', 'wall_4_end')
def change(self):
self.draw_preview()
def action_create_order_rectanglemaps(self):
action = self.env["ir.actions.actions"]._for_xml_id("rectanglemaps.action_rectanglemaps_create_order")
ctx = {'default_event_booth_id': self.id,
'default_event_id': self.event_id.id if self.event_id else False,
'default_partner_id': self.partner_id.id if self.partner_id else False
}
action['context'] = ctx
return action
You are trying to get a field value ( halle_id
) in create function before calling supper
:您正在尝试在调用
supper
之前在 create function 中获取字段值( halle_id
):
@api.model
def create(self, values):
if self.halle_id != False:
values['event_id'] = self.halle_id.event_id.id
return super(EventBooth, self).create(values)
self
is an empty recordset and the field values are not available self
是一个空记录集,并且字段值不可用
halle_id
and event_id
are of type Many2one
and their values will be empty recordsets, self.halle_id != False
expression will be evaluated to True
and Odoo will set the value of event_id
in values to False
because the value of the id
field of an empty recordset is False
then it will raise an error because the required field event_id
is not set. halle_id
和event_id
是Many2one
类型,它们的值将是空记录集, self.halle_id != False
表达式将被评估为True
并且 Odoo 会将值中event_id
的值设置为False
,因为空记录集的id
字段的值为False
则将引发错误,因为未设置必填字段event_id
。
You can call super and then get the halle_id
field value:您可以调用 super 然后获取
halle_id
字段值:
@api.model
def create(self, values):
res = super(EventBooth, self).create(values)
# Now you can use `res.halle_id`
return res
Or use its value in values
as an integer:或者将其
values
用作 integer:
self.halle_id.browse(values['halle_id'])
Note that you can use onchange decorator to fill the value of the event_id
when the value of halle_id
changes注意,当
halle_id
的值发生变化时,可以使用onchange装饰器填充event_id
的值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.