Odoo 11 Qweb Custom Report : Error to render compiling AST TypeError: 'NoneType' object is not callable
Odoo 11 Qweb Custom Report : Error to render compiling AST TypeError: 'NoneType' object is not callable
第一次在这里发表东西,希望能成功!
我正在尝试在 Odoo 11 中创建自定义报告,在我创建的自定义模块中,我遵循了我可以收集到的数据,但我无法解决以下问题。
- 所以我创建了这样的报告:
<report
id="production_order_report2"
model="pb.orders.products"
string="Production Order (English)"
report_type="qweb-pdf"
name="probespoketest.production_order_report_en2_template"
file="probespoketest.production_order_report_en2_template"
attachment_use="False"
/>
- 我的 Qweb 报告是:
<template id="production_order_report_en2_template">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="web.internal_layout">
<div class="page">
<h2>Report title</h2>
<p>This object's name is</p>
<t t-esc="testing()"/>
</div>
</t>
</t>
</t>
</template>
- 我的 python 代码是:
from odoo import api, fields, models, _
class OrderProductsFunctions(models.AbstractModel):
_name = 'report.probespoketest.production_order_report_en2_template'
def _testing(self):
result = 0
return result
- 我的错误是:
Odoo Server Error
Traceback (most recent call last):
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 342, in _compiled_fn
return compiled(self, append, new, options, log)
File "<template>", line 1, in template_1454_24554
File "<template>", line 2, in body_call_content_24553
File "<template>", line 3, in foreach_24552
File "<template>", line 4, in body_call_content_24551
TypeError: 'NoneType' object is not callable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo/odoo11/addons/web/controllers/main.py", line 1617, in report_download
response = self.report_routes(reportname, docids=docids, converter='pdf')
File "/opt/odoo/odoo11/odoo/http.py", line 516, in response_wrap
def response_wrap(*args, **kw):
File "/opt/odoo/odoo11/addons/web/controllers/main.py", line 1566, in report_routes
pdf = report.with_context(context).render_qweb_pdf(docids, data=data)[0]
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_actions_report.py", line 628,
in render_qweb_pdf
html = self.with_context(context).render_qweb_html(res_ids, data=data)[0]
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_actions_report.py", line 666,
in render_qweb_html
return self.render_template(self.report_name, data), 'html'
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_actions_report.py", line 470,
in render_template
return view_obj.render_template(template, values)
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_ui_view.py", line 1195, in render_template
return self.browse(self.get_view_id(template)).render(values, engine)
File "/opt/odoo/odoo11/addons/web_editor/models/ir_ui_view.py", line 27, in
render
return super(IrUiView, self).render(values=values, engine=engine)
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_ui_view.py", line 1204, in render
return self.env[engine].render(self.id, qcontext)
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/ir_qweb.py", line 57, in
render
return super(IrQWeb, self).render(id_or_xml_id, values=values, **context)
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 271, in render
self.compile(template, options)(self, body.append, values or {})
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 349, in _compiled_fn
raise QWebException("Error to render compiling AST", e, path, node and etree.tostring(node[0], encoding='unicode'), name)
odoo.addons.base.ir.ir_qweb.qweb.QWebException: 'NoneType' object is not callable
Traceback (most recent call last):
File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 342, in _compiled_fn
return compiled(self, append, new, options, log)
File "", line 1, in template_1454_24554
File "", line 2, in body_call_content_24553
File "", line 3, in foreach_24552
File "", line 4, in body_call_content_24551
TypeError: 'NoneType' object is not callable
Error to render compiling AST
TypeError: 'NoneType' object is not callable
Template: 1454
Path: /templates/t/t/t/t/div/t
Node: <t t-esc="testing()"/>
manifest.py 和两个 init.py 应该可以,但如果需要我可以提供代码。
也许问题是我应该调用方法 testing() 添加一些东西。如果我尝试这样做:
> <t t-esc="docs.testing()"/>
然后我得到:
> Error to render compiling AST AttributeError: 'pb.orders.products' object has no attribute 'testing' Template: 1454 Path:
> /templates/t/t/t/t/div/t Node: <t t-esc="docs.testing()"/>
因为我的测试方法存储在另一个模块中,该模块依赖于我尝试修改的模块。但是不知道怎么解决...
=== 编辑 ===
@WaKo
根据您的回答,我在 models.py 中对此进行了编码(在编码 pb.orders.products 的模块中,又名 "probespokeq"):
class OrderProductsFunctions(models.AbstractModel):
_name = 'report.probespokeq.production_order_report_en2_template'
def _testing(self):
result = 0
return result
@api.model
def render_html(self, docids, data=None):
report_obj = self.env['report']
report = report_obj._get_report_from_name('probespokeq.production_order_report_en2_template')
docargs = {
'doc_ids': docids,
'doc_model': report.pb.orders.products,
'docs': self,
'testing': self._testing, # You need to add this line
}
return report_obj.render('probespokeq.production_order_report_en2_template', docargs)
但是,我仍然收到相同的错误消息。任何的想法 ?
===== 编辑 2 ====
所以,现在我根据@WaKo 的建议将 class 更改为 get_report_values
而不是 render_html
,所以它看起来像这样:
class OrderProductsFunctions(models.AbstractModel):
_name = 'report.probespokeq.production_order_report_en2_template'
def _testing(self):
result = 0
return result
@api.multi
def get_report_values(self, docids, data=None):
docs = self.env['pb.orders.products'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'pb.orders.products',
'docs': docs,
'testing': self._testing, # You need to add this line
}
所以,现在我将 xml 更改如下:
> <?xml version="1.0"?> <t
> t-name="probespokeq.production_order_report_en2_template"> <t
> t-call="web.html_container">
> <t t-foreach="docs" t-as="o">
> <t t-call="web.internal_layout">
> <div class="page">
> <h2>Report title</h2>
> <p>This object's name is probespokeq</p>
> <t t-esc="o.testing()"/>
> </div>
> </t>
> </t>
> </t> </t>
然后我得到:
> Error to render compiling AST AttributeError: 'pb.orders.products'
> object has no attribute 'testing' Template: 1455 Path:
> /templates/t/t/t/t/div/t Node: <t t-esc="o.testing()"/>
要像以前那样在报告模板中使用 testing
,您应该在 custom report parser 中定义它并将其添加到 docargs
字典中。
from odoo import api, models
class ParticularReport(models.AbstractModel):
_name = 'report.module.report_name'
def _testing(self):
result = 0
return result
@api.model
def render_html(self, docids, data=None):
report_obj = self.env['report']
report = report_obj._get_report_from_name('module.report_name')
docargs = {
'doc_ids': docids,
'doc_model': report.model,
'docs': self,
'testing': self._testing, # You need to add this line
}
return report_obj.render('module.report_name', docargs)
您还可以在 pb.orders.products
中定义 testing
方法并在您的模板中使用 o.testing()
。
您可以找到覆盖 get_report_values 函数的自定义报告示例:
@api.multi
def get_report_values(self, docids, data=None):
docs = self.env['pb.orders.products'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'pb.orders.products',
'docs': docs,
'testing': self._testing, # You need to add this line
}
示例
要使用模型中的方法:
class PBOrdersProducts(models.Model):
_name = "pb.orders.products"
name = fields.Char()
def testing(self):
result = 0
return result
并使用:
<t t-esc="o.testing()"/>
在模板中。
要像在 sale
模块中那样使用自定义解析器:
class ParticularReport(models.AbstractModel):
_name = 'report.test.production_order_report'
def _testing(self):
result = 0
return result
@api.multi
def get_report_values(self, docids, data=None):
docs = self.env['pb.orders.products'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'pb.orders.products',
'docs': docs,
'testing': self._testing, # You need to add this line
}
在这种情况下,您需要使用:
<t t-esc="testing()"/>
第一次在这里发表东西,希望能成功!
我正在尝试在 Odoo 11 中创建自定义报告,在我创建的自定义模块中,我遵循了我可以收集到的数据,但我无法解决以下问题。
- 所以我创建了这样的报告:
<report id="production_order_report2" model="pb.orders.products" string="Production Order (English)" report_type="qweb-pdf" name="probespoketest.production_order_report_en2_template" file="probespoketest.production_order_report_en2_template" attachment_use="False" />
- 我的 Qweb 报告是:
<template id="production_order_report_en2_template"> <t t-call="web.html_container"> <t t-foreach="docs" t-as="o"> <t t-call="web.internal_layout"> <div class="page"> <h2>Report title</h2> <p>This object's name is</p> <t t-esc="testing()"/> </div> </t> </t> </t> </template>
- 我的 python 代码是:
from odoo import api, fields, models, _ class OrderProductsFunctions(models.AbstractModel): _name = 'report.probespoketest.production_order_report_en2_template' def _testing(self): result = 0 return result
- 我的错误是:
Odoo Server Error Traceback (most recent call last): File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 342, in _compiled_fn return compiled(self, append, new, options, log) File "<template>", line 1, in template_1454_24554 File "<template>", line 2, in body_call_content_24553 File "<template>", line 3, in foreach_24552 File "<template>", line 4, in body_call_content_24551 TypeError: 'NoneType' object is not callable During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/opt/odoo/odoo11/addons/web/controllers/main.py", line 1617, in report_download response = self.report_routes(reportname, docids=docids, converter='pdf') File "/opt/odoo/odoo11/odoo/http.py", line 516, in response_wrap def response_wrap(*args, **kw): File "/opt/odoo/odoo11/addons/web/controllers/main.py", line 1566, in report_routes pdf = report.with_context(context).render_qweb_pdf(docids, data=data)[0] File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_actions_report.py", line 628,
in render_qweb_pdf html = self.with_context(context).render_qweb_html(res_ids, data=data)[0] File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_actions_report.py", line 666, in render_qweb_html return self.render_template(self.report_name, data), 'html' File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_actions_report.py", line 470, in render_template return view_obj.render_template(template, values) File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_ui_view.py", line 1195, in render_template return self.browse(self.get_view_id(template)).render(values, engine) File "/opt/odoo/odoo11/addons/web_editor/models/ir_ui_view.py", line 27, in render return super(IrUiView, self).render(values=values, engine=engine) File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_ui_view.py", line 1204, in render return self.env[engine].render(self.id, qcontext) File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/ir_qweb.py", line 57, in render return super(IrQWeb, self).render(id_or_xml_id, values=values, **context) File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 271, in render self.compile(template, options)(self, body.append, values or {}) File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 349, in _compiled_fn raise QWebException("Error to render compiling AST", e, path, node and etree.tostring(node[0], encoding='unicode'), name) odoo.addons.base.ir.ir_qweb.qweb.QWebException: 'NoneType' object is not callable Traceback (most recent call last): File "/opt/odoo/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 342, in _compiled_fn return compiled(self, append, new, options, log) File "", line 1, in template_1454_24554 File "", line 2, in body_call_content_24553 File "", line 3, in foreach_24552 File "", line 4, in body_call_content_24551 TypeError: 'NoneType' object is not callable
Error to render compiling AST TypeError: 'NoneType' object is not callable Template: 1454 Path: /templates/t/t/t/t/div/t Node: <t t-esc="testing()"/>
manifest.py 和两个 init.py 应该可以,但如果需要我可以提供代码。
也许问题是我应该调用方法 testing() 添加一些东西。如果我尝试这样做:
> <t t-esc="docs.testing()"/>
然后我得到:
> Error to render compiling AST AttributeError: 'pb.orders.products' object has no attribute 'testing' Template: 1454 Path:
> /templates/t/t/t/t/div/t Node: <t t-esc="docs.testing()"/>
因为我的测试方法存储在另一个模块中,该模块依赖于我尝试修改的模块。但是不知道怎么解决...
=== 编辑 ===
@WaKo
根据您的回答,我在 models.py 中对此进行了编码(在编码 pb.orders.products 的模块中,又名 "probespokeq"):
class OrderProductsFunctions(models.AbstractModel):
_name = 'report.probespokeq.production_order_report_en2_template'
def _testing(self):
result = 0
return result
@api.model
def render_html(self, docids, data=None):
report_obj = self.env['report']
report = report_obj._get_report_from_name('probespokeq.production_order_report_en2_template')
docargs = {
'doc_ids': docids,
'doc_model': report.pb.orders.products,
'docs': self,
'testing': self._testing, # You need to add this line
}
return report_obj.render('probespokeq.production_order_report_en2_template', docargs)
但是,我仍然收到相同的错误消息。任何的想法 ?
===== 编辑 2 ====
所以,现在我根据@WaKo 的建议将 class 更改为 get_report_values
而不是 render_html
,所以它看起来像这样:
class OrderProductsFunctions(models.AbstractModel): _name = 'report.probespokeq.production_order_report_en2_template' def _testing(self): result = 0 return result @api.multi def get_report_values(self, docids, data=None): docs = self.env['pb.orders.products'].browse(docids) return { 'doc_ids': docs.ids, 'doc_model': 'pb.orders.products', 'docs': docs, 'testing': self._testing, # You need to add this line }
所以,现在我将 xml 更改如下:
> <?xml version="1.0"?> <t
> t-name="probespokeq.production_order_report_en2_template"> <t
> t-call="web.html_container">
> <t t-foreach="docs" t-as="o">
> <t t-call="web.internal_layout">
> <div class="page">
> <h2>Report title</h2>
> <p>This object's name is probespokeq</p>
> <t t-esc="o.testing()"/>
> </div>
> </t>
> </t>
> </t> </t>
然后我得到:
> Error to render compiling AST AttributeError: 'pb.orders.products'
> object has no attribute 'testing' Template: 1455 Path:
> /templates/t/t/t/t/div/t Node: <t t-esc="o.testing()"/>
要像以前那样在报告模板中使用 testing
,您应该在 custom report parser 中定义它并将其添加到 docargs
字典中。
from odoo import api, models
class ParticularReport(models.AbstractModel):
_name = 'report.module.report_name'
def _testing(self):
result = 0
return result
@api.model
def render_html(self, docids, data=None):
report_obj = self.env['report']
report = report_obj._get_report_from_name('module.report_name')
docargs = {
'doc_ids': docids,
'doc_model': report.model,
'docs': self,
'testing': self._testing, # You need to add this line
}
return report_obj.render('module.report_name', docargs)
您还可以在 pb.orders.products
中定义 testing
方法并在您的模板中使用 o.testing()
。
您可以找到覆盖 get_report_values 函数的自定义报告示例:
@api.multi
def get_report_values(self, docids, data=None):
docs = self.env['pb.orders.products'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'pb.orders.products',
'docs': docs,
'testing': self._testing, # You need to add this line
}
示例
要使用模型中的方法:
class PBOrdersProducts(models.Model):
_name = "pb.orders.products"
name = fields.Char()
def testing(self):
result = 0
return result
并使用:
<t t-esc="o.testing()"/>
在模板中。
要像在 sale
模块中那样使用自定义解析器:
class ParticularReport(models.AbstractModel):
_name = 'report.test.production_order_report'
def _testing(self):
result = 0
return result
@api.multi
def get_report_values(self, docids, data=None):
docs = self.env['pb.orders.products'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'pb.orders.products',
'docs': docs,
'testing': self._testing, # You need to add this line
}
在这种情况下,您需要使用:
<t t-esc="testing()"/>