WTForms FileField AttributeError: 'unicode' object has no attribute 'filename'

WTForms FileField AttributeError: 'unicode' object has no attribute 'filename'

Flask + Sqlalchemy + WTForms

代码之前运行良好,现在零更改我收到一条错误消息:

工作={"name":form.command.data.filename[:-3], AttributeError: 'unicode' 对象没有属性 'filename'

这当然非常令人困惑,因为直到今天早上它一直运行良好并且非常具有文件名属性。

下面我附上了表单代码和相关的视图创建代码,为了安全起见,对一些信息进行了编辑。

表单代码:

class DkronJobForm(FlaskForm):

command = FileField("Python File", validators=[DataRequired()])
schedule = StringField('Schedule', validators=[DataRequired()]) 
timezone = QuerySelectField(query_factory=lambda: Timezone.query.all(), get_label="name", default=lambda: Timezone.query.filter(Timezone.timezoneid == '418').one_or_none())
owner = StringField('Owner/Job Creator', validators=[DataRequired()])
owner_email = StringField("Owner's Email", validators=[Email()])
executor = StringField("Executor: (default=shell)", default="shell", validators=[DataRequired()])

#advanced options
exec_shell= BooleanField('Executor config: Shell (default = true)', default=True)
disable = BooleanField('Disable Job', default=False)
tags = StringField('Tags: Target nodes tags of this job', default=None)
retries = IntegerField('# of job retries if failed', default=0)

查看创建代码:

@admin.route('/dkron', methods=['GET','POST'])
def dkron_job():

global to_upload

check_BI_permission()

dkron = Dkron.query.all()
form=DkronJobForm()
null = None

if form.validate_on_submit():

    # save current and change to new working directory
    os.chdir("<path removed>")


    #creating json file from WTForm
    job = {"name": form.command.data.filename[:-3],
           "timezone": form.timezone.data.name,
           "shell": True, 
           "schedule": form.schedule.data,
           "environment_variables": null,
           "command":"",
           "owner": form.owner.data,
           "owner_email": form.owner_email.data,
           "disabled": form.disable.data,
           "tags": tags,
           "retries": form.retries.data,
           "dependent_jobs": null,
           "last_success":"0001-01-01T00:00:00Z",
           "last_error":"0001-01-01T00:00:00Z",
           "success_count":0,
           "error_count":0,
           "parent_job": "",
           "processors": null,
           "concurrency": "allow",
           "executor": form.executor.data,
           "executor_config": {"command": "<info removed>}}

    with open(form.command.data.filename[:-3] + '.json', 'w') as outfile:
        json.dump(job, outfile, ensure_ascii=False)

    # saving python script to correct location
    form.command.data.save('<path removed>'+form.command.data.filename)

    # uploading job to Dkron
    to_upload = form.command.data.filename[:-3] + '.json'

    cc="allow"


    new_job = Dkron(name=form.command.data.filename[:-3], 
                        timezone = form.timezone.data.name, 
                        schedule = form.schedule.data,
                        owner = form.owner.data,
                        owner_email = form.owner_email.data,
                        disabled = form.disable.data,
                        tags = form.tags.data,
                        retries = form.retries.data,
                        concurrency = cc,
                        executor = form.executor.data,
                        exec_command = form.command.data,
                        exec_shell = form.exec_shell.data)

    os.chdir("<path removed>")

    with open(form.command.data.filename[:-3]+".sh", "a+") as bash_file:
        bash_file.write("<code removed>+form.command.data.filename)

    os.chdir("<path removed>")

    try:    
        os.system("python JOBPOST_dkron.py "+ form.command.data.filename[:-3]+".json")
        db.session.merge(new_job)
        db.session.commit()
        return redirect(url_for('admin.dkron_job'))
    except:
        flash('Sorry an error occurred while attempting to commit the job.')
        return redirect(url_for('admin.dkron_job'))

return render_template('admin/dkron.html',form=form, dkron=dkron,
                       title='Dkron')

根据我的个人研究,我看到前段时间有一个解决方案需要 form = Form(request.form) 变成 form = Form(),但是正如您所见,这不是这里的问题。

我很困惑,任何帮助将不胜感激!非常感谢。

我建议你看一下 Filefield documentation 甚至源代码,看看在 Filefield 中不会有 filename 属性,但实际发送的文件名会在 field.data,所以在你的情况下 form.command.data

P.S。此外,删除最后 3 个符号是摆脱文件扩展名的糟糕方法,请改用 stdlib os.path.splitext