Предварительно заполнить Flask -WTF FileField, когда файл уже был загружен - PullRequest
1 голос
/ 04 августа 2020

вот чего я хотел бы достичь:

Я хотел бы иметь возможность редактировать запись в базе данных через форму, содержащую несколько различных типов полей (BooleandFields, StringFields и т. Д. c.) И в них два flask_wtf FileFields, которые я хотел бы предварительно заполнить (с именем файла), когда я уже загрузил бы файлы, поэтому мне не нужно повторно загружать x копий одного и того же, когда я просто хочу измените некоторые записи в других полях.

вот где я стою:

Все остальные поля (кроме FileFields) правильно предварительно заполнены, когда я вхожу в форму для ее редактирования. Я могу загрузить файл с помощью комбинации Flask -Uploads и UploadSet. через flask_wtf.file FileField. В своей базе данных я сохраняю имя файла и URL-адрес файла как строки.

Я прочитал flask -wtf загрузку файла , а также документацию WTForms и я чувствую себя немного потерянным из-за того, что мне нужно сделать, чтобы подражать тому, что нужно форме, чтобы заполнить FileField, как будто я уже

Вот фрагменты кода, который я использую:

  1. init.py
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_bootstrap import Bootstrap
from flask_uploads import UploadSet, configure_uploads
[...]

app = Flask(__name__)

[...] 
csvfiles = UploadSet('csvfiles')
configure_uploads(app, (csvfiles,))

forms.py

Здесь рассматриваются поля FileFields: "dive_posiview" и "dive_ctd"

from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired
from wtforms import StringField, IntegerField, DecimalField, SubmitField,BooleanField
from app import csvfiles
from app.models import User
import re

class DiveForm(FlaskForm):
  nb                = IntegerField('Dive Number', validators=[DataRequired()])
  max_depth         = IntegerField('Maximum Depth', validators=[DataRequired()])
  launch            = StringField("Launch Position: XX°XX.XXXX'N / XX°XX.XXXX'E ", validators=[InputRequired(),validate_Lat_Lon])
  recovery          = StringField("Recovery Position: XX°XX.XXXX'N / XX°XX.XXXX'E ", validators=[InputRequired(),validate_Lat_Lon])
  launch_datetime   = DateTimeLocalField('Launch Time',format='%Y-%m-%dT%H:%M', validators=[InputRequired()])
  recovery_datetime = DateTimeLocalField('Recovery Time',format='%Y-%m-%dT%H:%M', validators=[InputRequired()])
  bottom_start_datetime = DateTimeField('Bottom start time',format='%H:%M', validators=[DataRequired()])
  bottom_start_depth = IntegerField('Bottom start depth', validators=[DataRequired()])
  bottom_end_datetime = DateTimeField('Bottom end time',format='%H:%M', validators=[DataRequired()])
  bottom_end_depth  = IntegerField('Bottom end depth', validators=[DataRequired()])
  dive_time_total   = DateTimeField('Dive total time',format='%H:%M', validators=[DataRequired()])
  dive_time_bottom  = DateTimeField('Bottom total time', format='%H:%M',validators=[DataRequired()])
  dive_posiview     = FileField('Posiview log', validators=[FileAllowed(csvfiles, 'CSV file only !')])
  dive_ctd          = FileField('CTD log', validators=[FileAllowed(csvfiles, 'CSV file only ! ')])
  [...] 
  submit            = SubmitField('Validate')
routes.py
@app.route('/cruises/<cruisename>/<diveId>/edit',methods=['GET','POST'])
def dive_edit(cruisename,diveId):
    try:
        c = Cruises.query.filter_by(name=cruisename).first_or_404()
        d = Dives.query.filter_by(cruise_id=c.id,id=diveId).first_or_404()
        if request.method == "POST":
            form = DiveForm(formdata = request.form)
            if form.validate_on_submit():
                dive = d
                dive.nb = form.nb.data
                dive.max_depth = form.max_depth.data
                dive.launch = form.launch.data
                dive.recovery = form.recovery.data
                dive.launch_datetime = form.launch_datetime.data
                dive.recovery_datetime = form.recovery_datetime.data
                dive.bottom_start_datetime = form.bottom_start_datetime.data
                dive.bottom_start_depth = form.bottom_start_depth.data
                dive.bottom_end_datetime = form.bottom_end_datetime.data
                dive.bottom_end_depth = form.bottom_end_depth.data
                dive.dive_time_total = form.dive_time_total.data
                dive.dive_time_bottom = form.dive_time_bottom.data

                dive_folder = cruisename+'/Dive'+str(form.nb.data)
                filename_posiview = csvfiles.save(request.files['dive_posiview'],folder=dive_folder)
                url_posiview = csvfiles.url(filename_posiview)
                filename_ctd = csvfiles.save(request.files['dive_ctd'],folder=dive_folder)
                url_ctd = csvfiles.url(filename_ctd)
                dive.posiview_filename = filename_posiview
                dive.posiview_url = url_posiview
                dive.ctd_filename = filename_ctd
                dive.ctd_url = url_ctd

                dive.sampling_nets = form.sampling_nets.data
                dive.sampling_shovel = form.sampling_shovel.data
                dive.sampling_drill = form.sampling_drill.data
                dive.sampling_niskin = form.sampling_niskin.data
                dive.sampling_push_cores = form.sampling_push_cores.data
                dive.sampling_he_sampler = form.sampling_he_sampler.data
                dive.sampling_arm_action = form.sampling_arm_action.data
                dive.sampling_GBS = form.sampling_GBS.data
                dive.sampling_GBC = form.sampling_GBC.data
                dive.sampling_IMGAM = form.sampling_IMGAM.data
                dive.sensor_CTD = form.sensor_CTD.data
                dive.sensor_CODA = form.sensor_CODA.data
                dive.sensor_sonar = form.sensor_sonar.data
                dive.sensor_MiniPos = form.sensor_MiniPos.data
                dive.sensor_MiniPos_calibrated = form.sensor_MiniPos_calibrated.data
                dive.action_device_deployed = form.action_device_deployed.data
                dive.action_device_recovered = form.action_device_recovered.data
                dive.action_mosaicing = form.action_mosaicing.data
                dive.action_3D_imaging = form.action_3D_imaging.data

                db.session.commit()
                # execute jupyter convert script for that dive
                if filename_ctd is not None and filename_posiview is not None:
                    summary_file_path = os.path.abspath(os.curdir)+'/app/static/jupyter/scientific_summary_dive'+str(form.nb.data)+'.html'
                    if not path.exists(summary_file_path) :
                        paths = "POSIVIEW_PATH="+csvfiles_path+'/'+filename_posiview
                        paths += " CTD_PATH="+csvfiles_path+'/'+filename_ctd
                        thread = threading.Thread(target=os.system, args=( (paths+" jupyter nbconvert --to html --execute app/static/jupyter/dive_scientific_summary.ipynb --output scientific_summary_dive"+str(form.nb.data)),))
                        thread.daemon = True
                        thread.start()

                return redirect(url_for('cruise',cruisename=cruisename))
        else :
            form = DiveForm(obj = d)
            # NOT WORKING  
            if os.path.isfile(csvfiles_path+'/'+d.ctd_filename) :
                form.dive_ctd.data = d.ctd_filename
            # NOT WORKING 
            if os.path.isfile(csvfiles_path+'/'+d.posiview_filename) :
                form.dive_posiview.data = d.posiview_filename
            
            return render_template('dive_new.html',title='edit dive',form = form , diveId = diveId)
    except Exception as e:
        flash(e)
        return render_template("500.html")

версии, которые я использую:

Python                            3.8.2
Flask                             1.1.1            
Flask-Uploads                     0.2.1         
Flask-WTF                         0.14.3 
WTForms                           2.3.1

Спасибо за помощь

...