Odoo发票PDF文件名自定义及日期字段校验问题
Odoo发票PDF文件名添加年月:处理空日期字段报错问题
问题场景
我需要修改Odoo中发票的PDF文件名,添加月份和年份信息。目前在「Printed Report Name」中使用以下代码可实现需求:
object._get_report_base_filename() +'_'+ str(object.invoice_date.month) +'_'+ str(object.invoice_date.year)
但该代码仅在invoice_date字段已设置时生效,草稿状态下发票无日期会触发报错:
500 AttributeError: 'bool' object has no attribute 'month' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/odoo/src/odoo/addons/web/controllers/main.py", line 2034, in report_download report_name = safe_eval(report.print_report_name, {'object': obj, 'time': time}) File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 348, in safe_eval raise ValueError('%s: "%s" while evaluating\n%r' % (ustr(type(e)), ustr(e), expr)) ValueError: : "'bool' object has no attribute 'month'" while evaluating "\tobject._get_report_base_filename() \t\t+'_'+ \tstr(object.invoice_date.month) \t\t+'_'+ \tstr(object.invoice_date.year)" ", "message": ": "'bool' object has no attribute 'month'" while evaluating "\tobject._get_report_base_filename() \t\t+'_'+ \tstr(object.invoice_date.month) \t\t+'_'+ \tstr(object.invoice_date.year)" ", "arguments": [": "'bool' object has no attribute 'month'" while evaluating "\tobject._get_report_base_filename() \t\t+'_'+ \tstr(object.invoice_date.month) \t\t+'_'+ \tstr(object.invoice_date.year)"], "context": {}}}
推测空值返回为False导致报错,尝试用if语句校验但Odoo提示语法不识别:
if (object.invoice_date == False): 'Jan' else: str(object.invoice_date.month)
求正确的日期字段校验方法。
解决方案
Odoo的safe_eval对表达式语法有严格限制,不支持多行if语句,必须使用单行三元表达式,同时先判断invoice_date是否非空,再访问其属性。以下是几种可行方案:
方案1:草稿状态显示当前系统年月
如果需要给草稿发票添加当前系统时间的年月作为占位符,使用以下代码:
object._get_report_base_filename() + '_' + (str(object.invoice_date.month) + '_' + str(object.invoice_date.year) if object.invoice_date else 'Draft_' + str(time.localtime().tm_mon) + '_' + str(time.localtime().tm_year))
逻辑:当invoice_date存在时用发票日期的年月,否则用当前系统时间的年月并添加Draft前缀区分状态。
方案2:仅在有日期时附加年月
如果草稿状态直接保留基础文件名,不添加年月,用以下代码:
object._get_report_base_filename() + (('_'+str(object.invoice_date.month)+'_'+str(object.invoice_date.year)) if object.invoice_date else '')
方案3:使用日期格式化函数简化代码
利用Odoo支持的strftime方法规范日期格式,同时处理空值:
object._get_report_base_filename() + (object.invoice_date.strftime('_%m_%Y') if object.invoice_date else '')
%m表示两位数字月份(01-12),%Y表示四位数字年份,生成的文件名格式更统一。
关键说明
- Odoo的
safe_eval仅支持单行合法Python表达式,不能包含多行代码或复杂流程控制语句。 time变量是safe_eval默认上下文的一部分,无需额外配置即可使用。
内容的提问来源于stack exchange,提问作者BenGn0815
相关产品推荐
相关产品推荐

