简体   繁体   English

Odoo 15“未设置必填字段”即使已明确选择

[英]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_idevent_idMany2one类型,它们的值将是空记录集, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM