如何使用字段 ID 计算数据库字段

How to compute a databasefield with the field-id

型号:

db.define_table('orders',
    Field('customer_id', db.customer)
    Field('order_id', 'string')
    )

我想要一个特殊的 order_id,例如 XY-150012,其中 XY 是客户名称的一部分,15 是年份,12 id orders 的实际记录 ID。我在模型中试过:

db.orders.order_id.compute = lambda r: "%s-%s00%s" % (db.customer(r['customer_id']).short, str(request.now.year)[2:], r['id'])

永远不会识别id,计算结果为None。如果我从计算行中删除 r['id'] 它会起作用。

编辑:

向模型添加额外字段 field('running_number', 'integer') 后,我可以访问该字段的内容。 有没有简单的方法来设置这个字段 default=db.orders.id?

解决方案:

根据 Anthony 的意见,并阅读有关 recursive selects 的内容,我想到了这个解决方案:

db.define_table('orders',
    Field('customer_id', db.customer),
    Field('order_id', 'string', default = None))

def get_order_id(id, short):
    y = str(request.now.year)[2:]
    return '%s-%s00%s' % (short, y, id)

def set_id_after_insert(fields,id):
    fields.update(id=id)

def set_order_id_after_update(s,f):
    row = s.select().first()
    if row['order_id'] == None:
        s.update_naive(order_id=get_order_id(row['id'], row['customer_id'].short)
    else:
        return

db.orders._after_insert.append(lambda f,id: set_id_after_insert(f,id))
db.orders._after_update.append(lambda s,f: set_order_id_after_update(s,f))

问题是记录 ID 直到记录被插入数据库后才知道,因为 id 字段是一个自动递增的整数字段,其值由数据库生成,而不是通过 web2py.

一个选项是定义一个 _after_insert callback 在插入后更新 order_id 字段:

def order_after_insert(fields, id):
    fields.update(id=id)
    db(db.order.id == id).update(order_id=db.order.order_id.compute(fields))
db.order._after_insert.append(order_after_insert)

您可能还想创建一个 _after_update 回调,但在那种情况下,请务必在定义时使用 both 回调中的 update_naive 参数Set(详见上文 link)。

根据 order_id 的使用方式,另一个选项可能是 virtual field