在Odoo v16模板表单中,我有一个选择字段“活动类型”,其中包含来自后端的记录(类似于Many2many标签小部件,但现在在门户中),将由用户选择,并且用户可以选择多于1条记录.
根据所选记录,每个活动类型 (div) 的新 3 个字段将出现并成为必填字段。
以门户用户身份登录时,此代码可以完美运行。但是,当“公共用户”访问此表单时,会出现标题为“活动类型”的字段,允许我选择多个记录。但是,需要出现的部分(div)没有出现。
<div class="col-md-12"
style="padding-top: 20px !important; padding-bottom: 20px !important;">
<label class="form-label" for="activity_type_ids">Activity Type</label>
<span
style="color: red;"> *
</span>
<select class="form-control js-example-basic-multiple col-xl-6 mb-1 new-get_data"
multiple="multiple" name="activity_type_ids" required="1"
id="activity_type_ids">
<t t-foreach="activity_ids" t-as="activity">
<option t-att-value="activity" t-esc="activity.name"/>
</t>
</select>
<input type="hidden" id="hidden_activity_ids" name="hidden_activity_ids"/>
<input type="hidden" id="hidden_activity_codes"
name="hidden_activity_codes"/>
</div>
<!-- Div for Construction Fields -->
<div class="col-md-6 activity-section" id="construction_fields"
style="padding-top: 20px !important; padding-bottom: 20px !important;">
<label class="form-label">Construction CR Number</label>
<input type="text" class="form-control" name="construction_cr_number"
placeholder="Construction CR Number"/>
<label class="form-label">Construction CR</label>
<span style="color: red;">
*
</span>
<input type="file" class="form-control" name="construction_cr"
accept="application/pdf"/>
<label class="form-label">Construction Activity Register</label>
<input type="file" class="form-control"
name="construction_activity_register" accept="application/pdf"/>
</div>
<!-- Div for Maintenance and Operation Fields -->
<div class="col-md-6 activity-section" id="maintenance_fields"
style="padding-top: 20px !important; padding-bottom: 20px !important;">
<label class="form-label">Maintenance CR Number</label>
<span
style="color: red;"> *
</span>
<input type="text" class="form-control" name="maintenance_cr_number"
placeholder="Maintenance CR Number"/>
<label class="form-label">Maintenance CR</label>
<span style="color: red;">
*
</span>
<input type="file" class="form-control" name="maintenance_cr"
accept="application/pdf"/>
<label class="form-label">Maintenance Activity Register</label>
<span
style="color: red;"> *
</span>
<input type="file" class="form-control" name="maintenance_activity_register"
accept="application/pdf"/>
</div>
<!-- ETC... -->
相关的JS(不适用于公共用户)是:
odoo.define('custom_field.Many2many_tag', function (require) {
var PublicWidget = require('web.public.widget');
var rpc = require('web.rpc');
const { _lt } = require('web.core');
// Used in new_supplier_registration_request template
var NewData = PublicWidget.Widget.extend({
selector: '.new-get_data',
start: function () {
this._super.apply(this, arguments);
// Initialize the select2 widget
$('.js-example-basic-multiple').select2({
placeholder: _lt('Select Activities'),
allowClear: true,
});
// Hide all activity sections initially on page load
$('.activity-section').hide();
// Add an event listener to capture selected values
$('#activity_type_ids').on('change', function () {
// Get the selected values
var selectedValues = $(this).val();
// Parse the IDs from the selected values as integers
var selectedIds = selectedValues.map(function (value) {
return parseInt(value.match(/\d+/)[0], 10);
});
// Perform an RPC call to get the activity codes based on selected IDs
console.log("Before RPC");
rpc.query({
model: 'supplier.registration.activity',
method: 'read',
args: [selectedIds, ['code']],
}).then(function (records) {
console.log("in RPC records >>>", records);
var codes = records.map(function (record) {
return record.code;
});
// Clear all activity sections initially
$('.activity-section').hide();
$('input').removeAttr('required'); // Remove required attribute from all inputs
// Iterate over codes to show the relevant divs and set required attributes
codes.forEach(function (code) {
switch (code) {
case 'construction':
$('#construction_fields').show(); // Show construction fields
$('#construction_fields input').attr('required', true); // Set required attribute for all inputs in the div
break;
case 'maintenance':
$('#maintenance_fields').show();
$('#maintenance_fields input').attr('required', true);
break;
case 'education':
$('#education_fields').show();
$('#education_fields input').attr('required', true);
break;
case 'food_supplies':
$('#food_supplies_fields').show();
$('#food_supplies_fields input').attr('required', true);
break;
case 'equipment_supplies':
$('#equipment_supplies_fields').show();
$('#equipment_supplies_fields input').attr('required', true);
break;
case 'medical_equipment':
$('#medical_equipment_fields').show();
$('#medical_equipment_fields input').attr('required', true);
break;
case 'event_organization':
$('#event_organization_fields').show();
$('#event_organization_fields input').attr('required', true);
break;
default:
console.log("No matching activity found for code:", code);
}
});
// Set the hidden input field with the retrieved activity codes
$('#hidden_activity_codes').val(codes.join(','));
// Also set the hidden input with the selected IDs
$('#hidden_activity_ids').val(selectedIds.join(','));
});
});
},
});
PublicWidget.registry.Many2many_tag = NewData;
return NewData;
});
在我的控制台中
RPC之前
没有别的,意味着当用户公开时它不执行 RPC! 当我尝试捕获错误时,我得到了
"Traceback (most recent call last):\n File \"/home/dzeuf/Odoo/
Wamy/Odoo16/odoo/http.py\", line 1636, in _serve_db\n return
service_model.retrying(self._serve_ir_http, self.env)\n File \"/
home/dzeuf/Odoo/Odoo16/odoo/service/model.py\", line 133, in
retrying\n result = func()\n File \"/home/dzeuf/Odoo/Wamy/
Odoo16/odoo/http.py\", line 1661, in _serve_ir_http\n
ir_http._authenticate(rule.endpoint)\n /
Odoo16/odoo/addons/base/models/ir_http.py\", line 127, in
_authenticate\n getattr(cls, f'_auth_method_{auth}')()\n File
\"/home/dzeuf/Odoo/Odoo16/odoo/addons/base/models/ir_http.py\",
106, in _auth_method_user\n raise
http.SessionExpiredException(\"Session
expired\")\nodoo.http.SessionExpiredException: Session expired\n"
message
:
"Session expired"
这是我的控制器
@route('/my/new/supplier_registration_request', type='http',
auth='public', csrf=False, save_session=False, website=True)
def new_supplier_registration_request_portal(self):
country_ids = request.env['res.country'].sudo().search([])
state_ids =
request.env['res.country.state'].sudo().search([])
job_ids = request.env['hr.job'].sudo().search([])
bank_id = request.env['res.bank'].sudo().search([])
enterprise_manager_id =
request.env['res.partner'].sudo().search([])
nationality_id = request.env['res.country'].sudo().search([])
lang_ids = request.env['res.lang'].sudo().search([('active',
'in', (True, False))])
activity_ids =
request.env['supplier.registration.activity'].sudo().search([])
values = ({
'country_ids': country_ids,
'state_ids': state_ids,
'job_ids': job_ids,
'bank_id': bank_id,
'enterprise_manager_id': enterprise_manager_id,
'nationality_id': nationality_id,
'lang_ids': lang_ids,
'activity_ids': activity_ids,
'page_name': 'new_supplier_registration_request',
})
return
request.render("wamy_supplier_portal.new_supplier_registration_reques
t", values)
我有:
def _prepare_portal_layout_values(self):
values = super(SupplierRegistrationRequestPortal,
self)._prepare_portal_layout_values()
if request.env.user:
user = request.env.user
else:
user = request.env['res.users'].browse(1)
values['user'] = user
return values
在我的安全 CSV 文件中
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_supplier_registration_activity_user,supplier.registration.activity,model_supplier_registration_activity,,1,1,1,1
终于是我的模板了
<template id="new_supplier_registration_request">
<t t-call="portal.portal_layout">
<t t-set="previous_section">/supplier_portal</t>
<t t-set="form_add" t-value="1"/>
<t t-set="no_breadcrumbs" t-value="1"/>
<t t-set="breadcrumbs_searchbar" t-value="False"/>
<div class="new_supplier_registration_request text-bold">
<form data-model_name="supplier.registration.request" role="role"
id="supplier_registration_request_form" action="/create/supplier_registration_request"
method="POST"
enctype="multipart/form-data" data-success-mode="redirect"
data-success-page="/contactus-thank-you">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
'supplier.registration.activity'
...
您可以在console.log(records)
之后使用
then(function (records) {
检查 rpc 答案吗?在您的 CSV 安全文件中,尝试使用 设置菜单 > 访问权限在模型
read
上为base.group_public 添加访问权限
'supplier.registration.activity'