在Odoo中,通常网站表单允许用户输入数据,提交后会调用相应的控制器,并在控制器指定的模型中创建记录。
在这篇博客中,我们将创建一个通用控制器,可用于在提交表单时在任何模型中创建记录。
1. 首先,我们必须创建一个带有输入字段的网站表单。
<template id="generic_controller_form" name="Generic Controller">
<t t-call="website.layout">
<div id="wrap" class="oe_structure oe_empty">
<section class="s_website_form" data-vcss="001" data-snippet="s_website_form">
<div class="container">
<section class="s_text_block pt40 pb40 o_colored_level " data-snippet="s_text_block">
<div class="container s_allow_columns">
<div class="row">
<div class="col-lg-8 mt-4 mt-lg-0">
<section class="s_website_form" data-vcss="001"
data-snippet="s_website_form">
<div class="container">
<form action="/generic_controller" method="post"
enctype="multipart/form-data"
class="o_mark_required" data-mark="*"
data-model_name=""
data-success-page="">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<input type="hidden" name="model" value="sale.order"/>
<div class="s_website_form_rows row s_col_no_bgcolor">
<div class="form-group col-12 s_website_form_field
s_website_form_custom s_website_form_required"
data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label"
style="width: 200px" for="name">
<span class="s_website_form_label_content">
Opportunity
</span>
<span class="s_website_form_mark">*</span>
</label>
<div class="col-sm">
<input id="name" type="text"
class="form-control s_website_form_input"
name="name" required=""
data-fill-with="name"/>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_field
s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label"
style="width: 200px" for="partner_id">
<span class="s_website_form_label_content">Customer</span>
<span class="s_website_form_mark">*</span>
</label>
<div class="col-sm">
<select name="partner_id" t-attf-class="form-control
s_website_form_input required="1">
<t t-foreach="partners or []"
t-as="partner">
<option t-att-value="partner.id">
<t t-esc="partner.name"/>
</option>
</t>
</select>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_field
s_website_form_required"
data-type="email" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label"
style="width: 200px" for="contact3">
<span class="s_website_form_label_content">Email
</span>
<span class="s_website_form_mark">*</span>
</label>
<div class="col-sm">
<input id="email" type="email"
class="form-control s_website_form_input"
name="email_from" required=""
data-fill-with="email"/>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_field
s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto
S_website_form_label” style=" width:
200px" for="phone">
<span class="s_website_form_label_content">Phone
</span>
</label>
<div class="col-sm">
<input id="phone" type="tel"
class="form-control s_website_form_input"
name="phone" data-fill-with="phone"/>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_field
s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto
s_website_form_label" style="width: 200px"
for="user_id">
<span class="s_website_form_label_content">Salesperson
</span>
<span class="s_website_form_mark">*</span>
</label>
<div class="col-sm">
<select name="user_id"
t-attf-class="form-control s_website_form_input"
required="1">
<t t-foreach="users or []" t-as="user">
<option t-att-value="user.id">
<t t-esc="user.name"/>
</option>
</t>
</select>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_field s_website_form_custom"
data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label"
style="width: 200px" for="team_id">
<span class="s_website_form_label_content">
Sales Team
</span>
<span class="s_website_form_mark">*</span>
</label>
<div class="col-sm">
<select name="team_id"
t-attf-class="form-control s_website_form_input"
required="1">
<t t-foreach="sales_team or []"
t-as="team">
<option t-att-value="team.id">
<t t-esc="team.name"/>
</option>
</t>
</select>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_submit"
data-name="Submit Button">
<div style="width: 200px;"
class="s_website_form_label"/>
<button type="submit" class="btn btn-primary">Submit
</button>
</div>
</div>
</form>
</div>
</section>
</div>
</div>
</div>
</section>
</div>
</section>
</div>
</t>
</template>
在创建表单模板时,我们需要将模型名称传递为<input type="hidden" name="model" value="sale.order"/>, 其中在值中,我们需要指定模型名称。此外,在模板定义中,我们可以将字段名称指定为表单字段的名称。
2.接下来,我们可以定义一个通用控制器,它将在提交表单后被调用
@http.route('/generic_controller', methods=['POST'], auth="public", website=True)
def menu_generic_controller_request_submit(self, **kw):
values = {}
fields = request.env['ir.model'].sudo().search([('model', '=',
kw.get('model'))]).field_id
for key, val in kw.items():
field_id = fields.sudo().filtered(lambda r: r.sudo().name == key).sudo()
if not field_id:
continue
if field_id.ttype == 'many2one':
val = int(val) if val else 0
values.update({
key: val
})
record = request.env[kw.get('model')].sudo().create(values)
return
http.request.render("generic_controller_app.generic_controller_form", {})
总之,提供的代码演示了如何在 Odoo 中创建通用控制器来处理来自网站的表单提交。通用控制器允许根据提交的表单数据在任何指定的模型中动态创建记录。这种方法增强了可重用性,并简化了在 Odoo 网站上为不同模型创建新表单的过程。