WTForms FileField AttributeError: у объекта 'unicode' нет атрибута 'filename' - PullRequest
0 голосов
/ 28 января 2019

Flask + Sqlalchemy + WTForms

Раньше код работал отлично, теперь с нулевым изменением я получаю сообщение об ошибке:

job = {"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 = Form (), однако, как вы можете видеть, здесь проблема не в этом.

Я совершенно сбит с толку, и любая помощь будет принята с благодарностью!Большое спасибо заранее.

1 Ответ

0 голосов
/ 28 января 2019

Я бы посоветовал вам взглянуть на документацию по Filefield или даже исходный код, чтобы увидеть, что в Filefield не будет атрибута filename, но фактическое имя отправленного файла будет в field.data, поэтому form.command.data в вашем случае.

PS Кроме того, удаление 3 последних символов - это плохой способ избавиться от расширения файла, используйте stdlib os.path.splitext .

...