on_apply
on_apply(self, delta, params, connection)
使用范围: server
编程语言: python
父类: Item 类
描述说明
在 on_apply 事件前后的事件,请参阅 doc:verson 7 </releases/version_7/index>
中的 on_before_apply_record 和 on_after_apply_record 。
当你需要在 client
或 server 上的 apply 方法执行中重写标准的数据保存过程时,
请编写 on_apply 事件处理程序。
请参阅 on_apply events
来理解如何触发 on_apply 事件。
on_apply 事件处理程序有下列参数:
delta- 一个包含数据项变更日志的增量(delta)数据(下文将详细讨论)params- 通过 apply 方法传递到服务端的参数connection- 用于将更改保存到数据库的连接
必须将 delta 参数包含的变更保存在数据库里。
就其本身而言,此选项是实体项的副本,其数据集是项目的更改日志。 记录更改的性质可以通过以下方法获得:
rec_insertedrec_modifiedrec_deleted
如果添加了、修改了、删除了记录,它们将分别返回 True
如果实体项有一个明细项,那么 delta 参数也有一个与之对应的明细项,用来存储实体明细项的更改。
备注
请注意,当从实体项中删除一个含有明细项记录的记录时,
变更日志将仅仅保存那个被删除的主记录,不会存储明细项中被删除的记录信息。
要添加这些被删除的明细项的记录,请调用 delta 的 update_deleted 方法。
光标移动到另一条记录后,您不需要打开增量(delta)明细信息。
增量(delta)数据集的字段含有一个 on_apply 属性,
此属性能用来获取发生变更之前时字段的值。
如果没有定义 on_apply 事件处理程序,
那么将执行 apply_delta 方法来生成并执行 SQL 查询语句。
之后,将返回相关的处理结果信息,其中也存储着新记录的 id 。
客户端根据这些信息更新实体项的变更日志和新记录的主键字段的值。
当 on_apply 事件处理程序返回 None 时,就会执行 apply_delta 方法。
你能对 delta 进行一些额外的处理过程。 在下面的代码中,在变更应用到数据库表中之前, date 字段的值被设置为当前的日期。
import datetime
def on_apply(item, delta, params, connection):
for d in delta:
d.edit()
d.date.value = datetime.datetime.now()
d.post()
备注
请注意,使用这种方法产生的变更不会反映在客户端的实体项数据集中。 你能够使用客户端的 refresh_record 或 refresh_page 方法来显示这些变更。
在 Jam.py V5 的以下代码中,在保存对发票所做的更改时,
应用程序会同时更新曲目(tracks)的 tracks_sold 字段值以及当前发票的相关值。
所有这些都是在一个事务中完成的。
def on_apply(item, delta, params, connection):
tracks = item.task.tracks.copy()
changes = {}
delta.update_deleted()
for d in delta:
for t in d.invoice_table:
if not changes.get(t.track.value):
changes[t.track.value] = 0
if t.rec_inserted():
changes[t.track.value] += t.quantity.value
elif t.rec_deleted():
changes[t.track.value] -= t.quantity.value
elif t.rec_modified():
changes[t.track.value] += t.quantity.value - t.quantity.old_value
ids = list(changes.keys())
tracks.set_where(id__in=ids)
tracks.open()
for t in tracks:
q = changes.get(t.id.value)
if q:
t.edit()
t.tracks_sold.value += q
t.post()
tracks.apply(connection)
在前面的示例中, on_apply 事件处理程序返回 None 。
在此之后,应用程序将执行 apply_delta 方法。
在 Jam.py V7 的以下代码中,我们执行了与服务器端计算相同且更多的操作。
注意明细项的 calc_track 函数:
def on_apply(item, delta, params, connection):
if not delta.rec_deleted():
calc_invoice(delta, connection)
def calc_invoice(delta, connection):
invoice = task.invoices.copy(handlers=False);
invoice.set_where(id=delta.id.value)
invoice.open(connection=connection)
invoice.subtotal.value = 0
invoice.tax.value = 0
invoice.total.value = 0
invoice.invoice_table.open(connection=connection)
for t in invoice.invoice_table:
task.invoice_table.calc_track(t)
invoice.subtotal.value += t.amount.value
invoice.tax.value += t.tax.value
invoice.total.value += t.total.value
invoice.apply(connection=connection)
delta.copy_record_fields(invoice, copy_system_fields=True)
在发票详细项的 Server Module 上,有:
def calc_track(item):
item.amount.value = item.quantity.value * item.unitprice.value
item.tax.value = item.amount.value * item.master.taxrate.value / 100
item.total.value = item.amount.value + item.tax.value
item.paid.value = item.master.paid.value
更一般的情况是:
def on_apply(item, delta, params, connection):
# execute some code before changes are written to the database
result = item.apply_delta(delta, params, connection)
# execute some code after changes are written to the database
return result