5

这是我想要实现的目标:

我希望能够通过包含多种不同类型字段(BooleandFields、StringFields 等)的表单来编辑数据库条目,其中有两个flask_wtf FileFields我希望在我之前预先填充(使用文件名)本来已经上传了文件,所以当我只想更改其他字段中的某些条目时,我不必重新上传相同内容的 x 个副本。

这是我的立场:

当我输入表单进行编辑时,所有其他字段(FileFields 除外)都已正确预填充。我可以使用 Flask-Uploads 和 UploadSet 的组合上传文件。通过一个flask_wtf.file FileField. 在我的数据库中,我将文件名和文件 url 保存为字符串。

我已经阅读了flask-wtf 文件上传以及WTForms 文档,我对我必须做的事情来模拟表单需要什么以便填充 FileField 好像我已经感到有点迷茫

以下是我正在使用的代码片段:

  1. 初始化文件
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,))

  1. 表格.py

这里有问题的文件字段是:“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')
  1. 路线.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

谢谢您的帮助

4

0 回答 0