odoo8 默认的create方法

odoo8 默认的create方法
osv.osv -->modules.py文件中

def create(self, vals):
    """ create(vals) -> record

    Creates a new record for the model.

    The new record is initialized using the values from ``vals`` and
    if necessary those from :meth:`~.default_get`.

    :param dict vals:
        values for the model's fields, as a dictionary::

            {'field_name': field_value, ...}

        see :meth:`~.write` for details
    :return: new record created
    :raise AccessError: * if user has no create rights on the requested object
                        * if user tries to bypass access rules for create on the requested object
    :raise ValidateError: if user tries to enter invalid value for a field that is not in selection
    :raise UserError: if a loop would be created in a hierarchy of objects a result of the operation (such as setting an object as its own parent)
    """
    self.check_access_rights('create')

    # add missing defaults, and drop fields that may not be set by user
    vals = self._add_missing_default_values(vals)
    for field in itertools.chain(MAGIC_COLUMNS, ('parent_left', 'parent_right')):
        vals.pop(field, None)

    # split up fields into old-style and pure new-style ones
    old_vals, new_vals, unknown = {}, {}, []
    for key, val in vals.iteritems():
        field = self._fields.get(key)
        if field:
            if field.column or field.inherited:
                old_vals[key] = val
            if field.inverse and not field.inherited:
                new_vals[key] = val
        else:
            unknown.append(key)

    if unknown:
        _logger.warning("%s.create() with unknown fields: %s", self._name, ', '.join(sorted(unknown)))

    # create record with old-style fields
    record = self.browse(self._create(old_vals))

    # put the values of pure new-style fields into cache, and inverse them
    record._cache.update(record._convert_to_cache(new_vals))
    for key in new_vals:
        self._fields[key].determine_inverse(record)

    return record

def _create(self, cr, user, vals, context=None):
    # low-level implementation of create()
    if not context:
        context = {}

    if self.is_transient():
        self._transient_vacuum(cr, user)

    tocreate = {}
    for v in self._inherits:
        if self._inherits[v] not in vals:
            tocreate[v] = {}
        else:
            tocreate[v] = {'id': vals[self._inherits[v]]}

    updates = [
        # list of column assignments defined as tuples like:
        #   (column_name, format_string, column_value)
        #   (column_name, sql_formula)
        # Those tuples will be used by the string formatting for the INSERT
        # statement below.
        ('id', "nextval('%s')" % self._sequence),
    ]

    upd_todo = []
    unknown_fields = []
    for v in vals.keys():
        if v in self._inherit_fields and v not in self._columns:
            (table, col, col_detail, original_parent) = self._inherit_fields[v]
            tocreate[table][v] = vals[v]
            del vals[v]
        else:
            if (v not in self._inherit_fields) and (v not in self._columns):
                del vals[v]
                unknown_fields.append(v)
    if unknown_fields:
        _logger.warning(
            'No such field(s) in model %s: %s.',
            self._name, ', '.join(unknown_fields))

    for table in tocreate:
        if self._inherits[table] in vals:
            del vals[self._inherits[table]]

        record_id = tocreate[table].pop('id', None)

        if record_id is None or not record_id:
            record_id = self.pool[table].create(cr, user, tocreate[table], context=context)
        else:
            self.pool[table].write(cr, user, [record_id], tocreate[table], context=context)

        updates.append((self._inherits[table], '%s', record_id))

    #Start : Set bool fields to be False if they are not touched(to make search more powerful)
    bool_fields = [x for x in self._columns.keys() if self._columns[x]._type=='boolean']

    for bool_field in bool_fields:
        if bool_field not in vals:
            vals[bool_field] = False
    #End
    for field in vals.keys():
        fobj = None
        if field in self._columns:
            fobj = self._columns[field]
        else:
            fobj = self._inherit_fields[field][2]
        if not fobj:
            continue
        groups = fobj.write
        if groups:
            edit = False
            for group in groups:
                module = group.split(".")[0]
                grp = group.split(".")[1]
                cr.execute("select count(*) from res_groups_users_rel where gid IN (select res_id from ir_model_data where name='%s' and module='%s' and model='%s') and uid=%s" % \
                           (grp, module, 'res.groups', user))
                readonly = cr.fetchall()
                if readonly[0][0] >= 1:
                    edit = True
                    break
                elif readonly[0][0] == 0:
                    edit = False
                else:
                    edit = False

            if not edit:
                vals.pop(field)
    for field in vals:
        current_field = self._columns[field]
        if current_field._classic_write:
            updates.append((field, '%s', current_field._symbol_set[1](vals[field])))

            #for the function fields that receive a value, we set them directly in the database
            #(they may be required), but we also need to trigger the _fct_inv()
            if (hasattr(current_field, '_fnct_inv')) and not isinstance(current_field, fields.related):
                #TODO: this way to special case the related fields is really creepy but it shouldn't be changed at
                #one week of the release candidate. It seems the only good way to handle correctly this is to add an
                #attribute to make a field `really readonly´ and thus totally ignored by the create()... otherwise
                #if, for example, the related has a default value (for usability) then the fct_inv is called and it
                #may raise some access rights error. Changing this is a too big change for now, and is thus postponed
                #after the release but, definitively, the behavior shouldn't be different for related and function
                #fields.
                upd_todo.append(field)
        else:
            #TODO: this `if´ statement should be removed because there is no good reason to special case the fields
            #related. See the above TODO comment for further explanations.
            if not isinstance(current_field, fields.related):
                upd_todo.append(field)
        if field in self._columns \
                and hasattr(current_field, 'selection') \
                and vals[field]:
            self._check_selection_field_value(cr, user, field, vals[field], context=context)
    if self._log_access:
        updates.append(('create_uid', '%s', user))
        updates.append(('write_uid', '%s', user))
        updates.append(('create_date', "(now() at time zone 'UTC')"))
        updates.append(('write_date', "(now() at time zone 'UTC')"))

    # the list of tuples used in this formatting corresponds to
    # tuple(field_name, format, value)
    # In some case, for example (id, create_date, write_date) we does not
    # need to read the third value of the tuple, because the real value is
    # encoded in the second value (the format).
    cr.execute(
        """INSERT INTO "%s" (%s) VALUES(%s) RETURNING id""" % (
            self._table,
            ', '.join('"%s"' % u[0] for u in updates),
            ', '.join(u[1] for u in updates)
        ),
        tuple([u[2] for u in updates if len(u) > 2])
    )

    id_new, = cr.fetchone()
    recs = self.browse(cr, user, id_new, context)

    if self._parent_store and not context.get('defer_parent_store_computation'):
        if self.pool._init:
            self.pool._init_parent[self._name] = True
        else:
            parent = vals.get(self._parent_name, False)
            if parent:
                cr.execute('select parent_right from '+self._table+' where '+self._parent_name+'=%s order by '+(self._parent_order or self._order), (parent,))
                pleft_old = None
                result_p = cr.fetchall()
                for (pleft,) in result_p:
                    if not pleft:
                        break
                    pleft_old = pleft
                if not pleft_old:
                    cr.execute('select parent_left from '+self._table+' where id=%s', (parent,))
                    pleft_old = cr.fetchone()[0]
                pleft = pleft_old
            else:
                cr.execute('select max(parent_right) from '+self._table)
                pleft = cr.fetchone()[0] or 0
            cr.execute('update '+self._table+' set parent_left=parent_left+2 where parent_left>%s', (pleft,))
            cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%s', (pleft,))
            cr.execute('update '+self._table+' set parent_left=%s,parent_right=%s where id=%s', (pleft+1, pleft+2, id_new))
            recs.invalidate_cache(['parent_left', 'parent_right'])

    # invalidate and mark new-style fields to recompute; do this before
    # setting other fields, because it can require the value of computed
    # fields, e.g., a one2many checking constraints on records
    recs.modified(self._fields)

    # call the 'set' method of fields which are not classic_write
    upd_todo.sort(lambda x, y: self._columns[x].priority-self._columns[y].priority)

    # default element in context must be remove when call a one2many or many2many
    rel_context = context.copy()
    for c in context.items():
        if c[0].startswith('default_'):
            del rel_context[c[0]]

    result = []
    for field in upd_todo:
        result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or []

    # for recomputing new-style fields
    recs.modified(upd_todo)

    # check Python constraints
    recs._validate_fields(vals)

    if context.get('recompute', True):
        result += self._store_get_values(cr, user, [id_new],
            list(set(vals.keys() + self._inherits.values())),
            context)
        result.sort()
        done = []
        for order, model_name, ids, fields2 in result:
            if not (model_name, ids, fields2) in done:
                self.pool[model_name]._store_set_values(cr, user, ids, fields2, context)
                done.append((model_name, ids, fields2))
        # recompute new-style fields
        recs.recompute()

    if self._log_create and context.get('recompute', True):
        message = self._description + \
            " '" + \
            self.name_get(cr, user, [id_new], context=context)[0][1] + \
            "' " + _("created.")
        self.log(cr, user, id_new, message, True, context=context)

    self.check_access_rule(cr, user, [id_new], 'create', context=context)
    self.create_workflow(cr, user, [id_new], context=context)
    return id_new
要在Odoo中嵌入视图,可以按照以下方法进行操作: 1. 使用看板视图进行嵌入:看板视图是一种可视化的视图,将记录显示为卡片,并可以按列分组。您可以在看板视图中设置属性,如default_group_bydefault_order,来定义视图的默认行为。您还可以使用属性examples来定义看板示例设置。 2. 使用表单视图进行嵌入:表单视图是Odoo中最常见的视图类型之一,您可以使用表单视图来显示编辑记录的详细信息。如果您想要在看板视图中进行记录的快速创建,可以设置quick_create属性为true。 3. 使用列表视图进行嵌入:列表视图以表格形式显示记录,并提供了排序、筛选分页等功能。您可以在列表视图中设置属性,如default_order,来定义记录的默认排序顺序。 总结起来,要在Odoo中嵌入视图,您可以使用看板视图、表单视图或列表视图,并根据您的需求设置相应的属性来定义视图的行为。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Odoo看板视图](https://blog.youkuaiyun.com/weixin_44141284/article/details/128813441)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [odoo14视图通过路由嵌入内容](https://blog.youkuaiyun.com/weixin_44565926/article/details/122139573)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值