Web2py SQLFORM更新或插入取决于在回调时检查的记录存在

时间:2015-08-26 12:12:21

标签: python web2py

我遇到了以下挑战。

我可以使用回调函数来决定是否更新记录或在form.process()调用中插入新记录吗?

简而言之,我需要一个SQLFORM,用户将填写文本参考标识符,并可选择上传文件。也就是说,他们应该能够上传一个带有引用的文件,或者只是插入一个新的引用,然后通过同一个SQLFORM将添加到其中。

型号:

db.define_table('t_object_occurence',
    Field('f_refid', type='string', label=T('Reference')),
    Field('f_object_id', db.t_object, label=T('Object')),
    Field('f_temp_file', type='upload', label=T('File'), autodelete=True)
    #more fileds
)

每当用户选择一个文件时,一些jQuery将根据文件名(正式定义)更新ref id字段。

查看:

{{if auth.has_permission('Object_occurence_UL'):}}
<h2>Add a new occurence</h2>
    {{=upload_form}}
{{pass}}
<h2>Latest occurences</h2>
{{=grid}}
<!-- some jQuery -->

然后,通过form.process()调用的回调函数执行以下检查(以及其他不可用的范围):

  1. 如果不存在具有相同ref id的记录,则此表单必须生成db插入。有或没有上传的文件。
  2. 如果有,2个主要案例:
    1. 现有记录已经有上传文件,然后应该提出表单错误=&gt;完成了
    2. 或者,如果此记录没有其文件,那么我希望通过上传文件来更新文件。
  3. 控制器:

    def object_browse():
        obj = db.t_object(request.args[0])
        upload_form = SQLFORM(db.t_object_occurence, fields=['f_refid', 'f_temp_file'])
        # recall object ID in form parameters
        upload_form.vars.f_object_id = long(request.args[0])
        # perform field values checks with specific function analyse_occurence_data()
        if upload_form.process(onvalidation=analyse_occurence_data).accepted:
            if upload_form.vars.f_temp_file != '':
                response.flash = "File upload OK, occurence " + str(upload_form.vars.f_refid) + " added to repository"
            else:
                response.flash = "New forcasted occurence added " + str(upload_form.vars.f_refid)
            redirect(URL('object_browse', args=[str(obj.id)], user_signature=True))
        # display occurence list
        query = (db.t_object_occurence.f_object_id==long(request.args[0]))
        grid = SQLFORM.grid(...)
        return dict(upload_form=upload_form, grid=grid)
    

    检查回调函数:

    def analyse_occurence_data(form):
        import types
        if isinstance(form.vars.f_temp_file, types.StringType):
            filename = None
        else:
            filename = form.vars.f_temp_file.filename
        occurence = form.vars.f_refid
        object_id = form.vars.f_object_id
        obj = db.t_object(object_id)
        # several checks and complementary form.vars.field = value
        potential_entry = db((db.t_object_occurence.f_refid==occurence)&(db.t_object_occurence.f_object_id==object_id)).select().first()
        if potential_entry is None:
            # let's insert a new record!
            return
        elif (filename is None) or (potential_entry.f_temp_file is not None):
            form.errors.f_temp_file = "The occurence "+occurence+" of "+obj.f_refid+" already exists in repository."
        elif potential_entry is not None:
                # THIS IS WHERE I'd like to decide to update instead of insert!
    

    由于我的应用程序在调用其回调之前无法知道它是否必须插入或更新记录,我正在寻找正确的指令,以便我的SQLFORM能做正确的事。

    非常感谢。

1 个答案:

答案 0 :(得分:1)

这是一个可以帮助您调整上述代码的工作示例:

def onvalidation_insert_or_update(form):
    row = db(db.mytable.f1 == form.vars.f1).select(db.mytable.ALL).first()
    if row is not None:
        id = row.id
        db(db.mytable.id == id).update(f2=form.vars.f2)
        session.flash = 'Record updated'
    else:
        id = db.mytable.insert(**form.vars)
        session.flash = 'Record inserted'
    db.commit()
    session.flash = 'Record inserted'
    redirect(URL(c='default', f='read_form', args=id))
    return


def basic_controller():
    form = SQLFORM(db.mytable)
    if form.process(dbio=False, onvalidation=onvalidation_insert_or_update).accepted:
        pass
    elif form.errors:
        response.flash = 'form has errors'
    else:
        response.flash = 'please fill the form'
    grid = SQLFORM.grid(db.mytable)
    return dict(form=form, grid=grid)

def read_form():
    form = SQLFORM(db.mytable, record=request.args(0), readonly=True)  # readonly=True make form not modifiable
    return dict(form=form)

我无法附加正在运行的应用程序......但是如果您向web2py用户google群组提出问题,我可以将其附加到电子邮件中,无论如何这对于此类问题更方便。