web2py:如何在使用 SQLFORM.smartgrid 删除之前执行指令 [英] web2py: How to execute instructions before delete using SQLFORM.smartgrid
问题描述
我使用 SQLFORM.smartgrid 显示表 (service_types)
中的记录列表.在智能网格的每一行都有一个删除链接/按钮来删除记录.我想在 smartgrid/web2py 实际删除记录之前执行一些代码,例如我想知道是否有引用此记录的子记录(services
表),如果有,则闪烁一条消息告诉用户该记录无法删除.这是怎么做的?
I use SQLFORM.smartgrid to show a list of records from a table (service_types)
. In each row of the smartgrid there is a delete link/button to delete the record. I want to executive some code before smartgrid/web2py actually deletes the record, for example I want to know if there are child records (services
table) referencing this record, and if any, flash a message telling user that record cannot be deleted. How is this done?
db.py
db.define_table('service_types',
Field('type_name', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()]),
format='%(type_name)s',
)
db.define_table('services',
Field('service_name',requires=[IS_NOT_EMPTY(),IS_NOT_IN_DB(db,'services.service_name')]),
Field('service_type','reference service_types',requires=IS_IN_DB(db,db.service_types.id,
'%(type_name)s',
error_message='not in table',
zero=None),
ondelete='RESTRICT',
),
Field('interest_rate','decimal(15,2)',requires=IS_DECIMAL_IN_RANGE(0,100)),
Field('max_term','integer'),
auth.signature,
format='%(service_name)s',
)
db.services._plural='Services'
db.services._singular='Service'
if db(db.service_types).count() < 1:
db.service_types.insert(type_name='Loan')
db.service_types.insert(type_name='Contribution')
db.service_types.insert(type_name='Other')
控制器
def list_services():
grid = SQLFORM.smartgrid(db.services
, fields = [db.services.service_name,db.services.service_type]
)
return locals()
查看
{{extend 'layout.html'}}
{{=grid}}
推荐答案
有两个选项.首先,deletable
参数可以是一个函数,它接受给定记录的 Row
对象并返回 True
或 False
> 指示记录是否可删除.如果返回False
,则该记录不会显示删除"按钮,服务器上也不允许进行删除操作.
There are two options. First, the deletable
argument can be a function that takes the Row
object of a given record and returns True
or False
to indicate whether the record is deletable. If it returns False
, the "Delete" button will not be shown for that record, nor the delete operation be allowed on the server.
def can_delete(row):
return True if [some condition involving row] else False
grid = SQLFORM.smartgrid(..., deletable=can_delete)
其次,有一个 ondelete
参数,它接受 db
Table
对象和记录 ID.它在删除操作之前被调用,因此为了防止删除,您可以在该函数内进行重定向:
Second, there is an ondelete
argument that takes the db
Table
object and the record ID. It is called right before the delete operation, so to prevent the delete, you can do a redirect within that function:
def ondelete(table, record_id):
record = table(record_id)
if [some condition]:
session.flash = 'Cannot delete this record'
redirect(URL())
grid = SQLFORM.smartgrid(..., ondelete=ondelete)
注意,如果网格是通过 Ajax 组件加载的,因此它的操作是通过 Ajax 执行的,那么在 ondelete
方法中使用 redirect
如上所示将无法正常工作,因为重定向将无效并且表格行仍会从浏览器的网格中删除(即使数据库记录没有被删除).在这种情况下,另一种方法是向浏览器返回一个非 200 HTTP 响应,这将阻止客户端 Javascript 从表中删除行(删除仅在 Ajax 请求成功时发生).我们还应该设置 response.flash
而不是 session.flash
(因为我们不会重定向/重新加载整个页面):
Note, if the grid is loaded via an Ajax component and its actions are therefore performed via Ajax, using redirect
within the ondelete
method as shown above will not work well, as the redirect will have no effect and the table row will still be deleted from the grid in the browser (even though the database record was not deleted). In that case, an alternative approach is to return a non-200 HTTP response to the browser, which will prevent the client-side Javascript from deleting the row from the table (the delete happens only on success of the Ajax request). We should also set response.flash
instead of session.flash
(because we are not redirecting/reloading the whole page):
def ondelete(table, record_id):
record = table(record_id)
if [some condition]:
response.flash = 'Cannot delete this record'
raise HTTP(403)
注意,deletable
和 ondelete
参数都可以是以表名作为键的字典,因此您可以为可能从智能网格链接的不同表指定不同的值.
Note, both the deletable
and ondelete
arguments can be dictionaries with table names as keys, so you can specify different values for different tables that might be linked from the smartgrid.
最后,请注意删除 URL 类似于 /appname/list_services/services/delete/services/[record ID]
.因此,在控制器中,您可以通过检查 request.args 中的 'delete' 是否正在请求删除.在这种情况下,
request.args[-2:]
表示表名和记录 ID,您可以使用它们进行任何检查.
Finally, notice the delete URLs look like /appname/list_services/services/delete/services/[record ID]
. So, in the controller, you can determine if a delete is being requested by checking if 'delete' in request.args
. In that case, request.args[-2:]
represents the table name and record ID, which you can use to do any checks.
这篇关于web2py:如何在使用 SQLFORM.smartgrid 删除之前执行指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!