5

here is what I would like to achieve:

I would like to be able to edit a database entry through a form which contains multiple different types of Fields (BooleandFields, StringFields etc.) and in these are two flask_wtf FileFields that I would like to have pre-populated (with the file name) when I would have already uploaded the files so I do not have to re-upload x copies of the same thing when I just want to change some entry in the other fields.

here is where I stand:

All the other fields (except the FileFields) are properly pre-populated when I enter the form to edit it. I am able to upload a file with the combination of Flask-Uploads and UploadSet. through a flask_wtf.file FileField. In my database I am saving the file name and the file url as Strings.

I have read the flask-wtf file upload as well as the WTForms documentation and I feel a bit lost with what I have to do to emulate what the form needs in order to have the FileField populated as if I already

Here are snippets of the code that I am using:

  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,))

  1. forms.py

The FileFields in question here are : "dive_posiview" and "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. 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")

the versions that I am using are :

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

Thanks for the help

ViVittori
  • 103
  • 1
  • 6

0 Answers0