Web2py CRUD.read() 记录在未填条件下创建

1 投票
1 回答
907 浏览
提问于 2025-04-17 05:35

我在Web2py中写了一个函数,目的是在数据库的一个表里根据条件创建记录,但即使条件没有满足,Web2py还是创建了记录。

这是我写的函数:

def buy_product():
    price = price_set(db,auth,'product')
    balance = limit(db,auth,'settings','account_balance')
    if balance !=None:
        if balance < price:
            form=redirect(URL('order'))
        else:
            form=crud.create(db.letter)
            if form.accepts(request.vars, session):
                tax = float(postage(form.vars.tax_type).replace("-","."))
                ##########################
                # I'm talking about this #
                ##########################
                if balance < (price + tax):
                    response.flash='You don\'t have enough balance to buy this product'
                    redirect(URL('not_processed'))
                else:
                    function_1(....)
                    ...
                    ...
                    update_field(db,auth,'settings','account_balance',-price)
                    response.flash='Done'
                    redirect(URL('products'))
                    pass
            elif form.errors:
                response.flash='Error 01'
            else:
                pass
            ###############################
    else:
        form=redirect(URL('settings'))
    return dict(form=form)

本来应该是,当余额 < 价格 + 税费时,用户应该被重定向到未处理页面,而不应该在数据库中创建新记录。

但是Web2py却在重定向用户到未处理的同时,还是创建了记录,并没有执行这部分代码,使用的是用户输入的信息。所以用户看到自己好像买了东西,但实际上并没有处理(见下文)。

        function_1(....)
        ...
        ...
        update_field(db,auth,'settings','account_balance',-price)
        response.flash='Done'
        redirect(URL('products'))
        pass

有什么想法吗?

谢谢!

1 个回答

3

Crud 这个工具会自己处理数据的插入和更新,所以它不需要用到 form.accepts。

你有两个选择:

1 - 使用 SQLFORM

    form=SQLFORM(db.letter)
    if form.accepts(request.vars, session):
        tax = float(postage(form.vars.tax_type).replace("-","."))
        ##########################
        # I'm talking about this #
        ##########################

2 - 使用 crud 事件

def myfunction(form):
    # do your stuff here
    # it will be called only when form is accepted

def myotherfunction(form):
    if form.errors:
        #do something here in case of errors
        #it will be called during the form validation

crud.settings.create_onvalidation = myotherfunction
crud.settings.create_onaccept = myfunction
#the above can be:
#crud.create_onaccept = lambda form: myfunction(form)

# define the above events before the creation of the form
form=crud.create(db.letter)

需要注意的是,SQLFORM 和 crud 有点不同。SQLFORM 需要你在 form.accepts 方法里验证表单,而 crud 是自己处理这些验证的,它会用到像 onvalidation 和 onaccept 这样的事件来进行自定义验证。

撰写回答