摘要:现在我们来给待办事项增加一个紧急程度的字段,用来表示当前任务的优先级。此处我们还给这个字段添加了默认值,表示当一个待办事项被创建后,如果没有指定紧急程度,将默认是待办状态。这篇教程中的代码同样会更新在我的仓库中。
在这篇教程里我们将会了解到 Odoo 模型里的一些其他类型的字段和特殊机制,而我依然会继续带领大家一起完善我们的 Todo 应用,不断地往里面添加一些新的功能特性,让它看起来更丰满也更实用一些。
选择字段在上一篇教程中,我们已经创建好了待办事项的模型,但是只是添加了「描述」和「已完成?」两个字段,这肯定是不能满足我们的需求的。现在我们来给待办事项增加一个「紧急程度」的字段,用来表示当前任务的优先级。
# models.py class TodoTask(models.Model): _name = "todo.task" _description = "待办事项" name = fields.Char("描述", required=True) is_done = fields.Boolean("已完成?") priority = fields.Selection([ ("todo", "待办"), ("normal", "普通"), ("urgency", "紧急") ], default="todo", string="紧急程度")
我们添加了一个 Selection 类型的字段 priority,并且指定了三个可供选择的程度类型,一般情况下,如果一个字段只有固定的几种可选值,通常都会选择使用 Selection 字段,它接受一个元组列表作为参数,其中元组的组成为 (value, string),左边的是数据库中存储的值,右边的是一个用于界面显示的描述。
此处我们还给这个字段添加了默认值 todo,表示当一个待办事项被创建后,如果没有指定紧急程度,将默认是待办状态。我们可以为任意类型的字段添加默认值。
在上一篇教程中我们提到过,在对模型进行改动之后,需要对模块进行升级才能看到变更后的样子,除了从应用列表中找到模块进行升级外,我们还可以在命令行中给 Odoo 的启动命令加上参数 -u todo 指定升级 todo 模块。
./odoo-bin --addons-path=addons,../mymodules --db-filter=^demo$ -d demo -u todo
升级后创建或打开任意一条待办事项进入到表单页面,就可以看到已经多了「紧急程度」这个字段了,并且默认选择了「待办」这一状态。
日期字段我们已经给待办事项加上紧急程度了,可是光有这个还不够,我们还要给它加上截止时间,毕竟 deadline 是第一生产力呀!
# models.py deadline = fields.Datetime(u"截止时间")
我们把截止日期也放到 TreeView 中,方便查看各个任务的 deadline
计算字段与视图装饰器
很多时候我们会需要用不同的颜色对待办事项进行标记,例如我们会希望已经过期的任务以红色标记来提醒我们,这个任务过期了。任务是否已经过期,我们要先知道任务的截止时间(上面一小节已经加上了)和当前时间,然后进行比较判断任务的截止时间是否小于当前时间,如果是则表示任务已经过期了,我们需要在视图上用红色将对应的任务标记起来。那将这个需求转化成代码应该怎么做呢?
这个需求跟时间有关,并且时间是流动(一直在变化)的,所以我们应该要有一个方法在用户每次打开待办事项之前,把这个结果计算好,并且反馈给用户,还好 Odoo 的 ORM 已经为我们实现了相关的机制——计算字段(Computed fields)
# models.py is_expired = fields.Boolean(u"已过期", compute="_compute_is_expired") @api.depends("deadline") @api.multi def _compute_is_expired(self): for record in self: if record.deadline: record.is_expired = record.deadline < fields.Datetime.now() else: record.is_expired = False
计算字段其实和其他字段一样,只不过多了一个 compute 属性,它的值是计算这个字段值的方法名。我们来看一下对应的方法 _compute_is_expired 头顶上的 @api.depends 这个装饰器,它接受了一个参数 deadline,表示的是 is_expired 这个字段的计算会用到 deadline 这个字段的值(我们需要用它的值和当前时间进行比较),如果一个计算字段会用到多个其他字段的值,这里就需要以逗号分隔,将用到的值的字段名依次传入装饰器中。
而 @api.multi 则表示该方法中的 self 是一个记录集(多个实例的集合),如果不理解,可以暂时不深究,到后面自然会知道这里的实际用法。
再来看看实际的计算逻辑部分,只有一个循环以及一条赋值语句,刚刚已经提到过这里的 self 表示一个记录集,我们需要对这个记录集里的每一条记录进行计算,判断这个待办事项是否已经过期,这里的 record 就是每一条记录的实例对象,我们用这条记录的 deadline 的值和当前时间 fields.Datetime.now() 进行比较,然后将结果赋值给字段 is_expired,就是这么简单。
PS: 这里我们对 deadline 进行了判断,是因为如果没有设置截止时间,又或者是在新建代办事项时,这里的 deadline 会是一个布尔值,是不能和时间字符串进行比较的。
其中大家可能会有疑问的应该是当前时间的获取,为什么不是用 datetime.now() 吧?实际上获取当前时间用的也是这个方法,只不过 Odoo 的 ORM 替我们封装了一层,fields.Datetime.now() 是类 Datetime 的静态方法:
# fields.py class Datetime(Field): type = "datetime" column_type = ("timestamp", "timestamp") column_cast_from = ("date",) @staticmethod def now(*args): """ Return the current day and time in the format expected by the ORM. This function may be used to compute default values. """ return datetime.now().strftime(DATETIME_FORMAT)
好的,这里先不过多纠结细节问题,现在我们已经可以计算出来每个待办事项是否已经过期了,那要怎么去用这个计算字段呢?我们打开视图文件来加点东西上去:
在视图中我们把 is_expired 字段加了进去,并且还加上了属性 invisible,这个属性的作用是将当前字段隐藏起来,因为这里我们不希望用户看到这个字段的值,而是将结果反映在颜色上。然后我们再看到
今天这篇教程的内容就先到这里了,下一篇再继续带大家深入更多的内容。这篇教程中的代码同样会更新在我的 GitHub 仓库中。
仓库地址:Odoo-Tutorial-Demo
写在最后距离上一次更新,已经过了好几个月了,这段时间除了忙公司的事情,还额外在做一些别的东西,然后最近在开发一个小程序。一直很想抽空出来更新这个系列的教程,一边又有很多事情在忙,拖更了实在是抱歉了!
如果你有任何的疑问,欢迎留言,我将会尽快给出答复,如果想要加群或者加好友,可以发送站内信给我,我会回复你微信号~
期待下一篇教程可以继续和你们见面。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/42255.html
摘要:虽然这是个很简单的应用,但是希望大家可以动手一起操作,从最简单的开始上手学习如何使用这个框架。则是在和之间,负责响应用户操作,从中获取数据进行处理并返回到中。 showImg(https://segmentfault.com/img/bV66tE?w=728&h=410); 在第一篇教程发布之后差不多一个月的今天,终于完成了第二篇内容,这个发布周期拖得实在是有点太长了,我都觉得不好意思...
摘要:今天这个系列教程即将迎来它的最后一篇内容了,我们将要来学习中权限相关的内容。在的权限管理体系中,同样也有用户组这一概念的存在,和其他框架如可以说大同小异。通常和权限相关的内容,我们都会在模块的目录下进行定义,记录集规则的定义自然也不例外。 在今年的情人节(2018.02.14)那天,我写了一篇博客说即将要开一个坑,也就是大家在看的这个系列的教程。今天这个系列教程即将迎来它的最后一篇内容...
摘要:在这一篇教程中,将会涉及到外键字段,可以将两个模型关联起来,然后很方便地获取到对应的数据。关联字段这一小节里,我们会给待办事项加上分类,并且这个分类可以让用户自己创建维护。今天这篇教程的内容就先到这里了,教程中的代码会更新在我的仓库中。 showImg(https://segmentfault.com/img/bVbfzvt?w=1280&h=795); 在这一篇教程中,将会涉及到外键...
摘要:大家好鸭,我又来更新啦还记得我们在第二篇教程中提到过的动作吗,今天我们就来专门讲讲在中的,学习不同类型的动作对应的应用场景,并且在我们的应用中使用上其中一些类型的动作。报表动作这类型的动作用于触发报表打印,例如打印发票等。 showImg(https://segmentfault.com/img/bVbhdTE?w=1471&h=845); 大家好鸭,我又来更新啦!还记得我们在第二篇教...
摘要:在前面教程中,我们使用了两种类型的视图和今天我们将学习使用另一种类型的视图搜索视图。大家可以试试看同时应用多个分组,或者将分组和过滤器组合使用,仔细观察和思考产生的结果。还是老规矩,教程中的代码会更新在仓库中。 showImg(https://segmentfault.com/img/bVbgO85?w=1950&h=1300); 在前面教程中,我们使用了两种类型的视图——TreeVi...
阅读 1769·2023-04-25 21:50
阅读 2417·2019-08-30 15:53
阅读 766·2019-08-30 13:19
阅读 2741·2019-08-28 17:58
阅读 2462·2019-08-23 16:21
阅读 2699·2019-08-23 14:08
阅读 1372·2019-08-23 11:32
阅读 1436·2019-08-22 16:09