Запись Web2py CRUD.read(), созданная при невыполненном условии

#python #crud #web2py

#python #crud #web2py

Вопрос:

Поэтому я использую функцию в 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)
  

предполагается, что когда Balance < price tax пользователь должен быть перенаправлен not_processed без создания новой записи в базе данных.

но web2py перенаправляет пользователя not_processed и создает запись, не выполняя эту часть с введенной информацией от пользователя. таким образом, пользователь видит, что он что-то купил, когда оно не обработано (см. Ниже)

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

есть идеи??

Спасибо

Ответ №1:

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 для пользовательских проверок.

Комментарии:

1. Вы также должны уметь делать: form = crud.create(db.letter, onvalidation=myvalidationfunction) SQLFORM и crud принимают аргументы onvalidation . Я полагаю, что затем вы можете проверить дополнительные условия и добавить ошибки, если эти условия не выполняются, используя form.errors.field = "Cannot do <something>" я упоминаю об этом только потому, что вам может не понадобиться одна функция onvalidation для всего CRUD, и у вас может быть веская причина использовать CRUD поверх SQLFORM (SQLFORM также принимает параметр onvalidation). Смотрите: web2py.com/books/default/chapter/29/7#onvalidation для большего