简体   繁体   中英

Can I use one WTForm for multiple @app.route's?

I need to access information from my WTForm in multiple @app.route's in my app.py , so that I can post data visualization for my app. Currently, I have a @app.route(/home/) page and user-entered text on this page is processed by a WTForm, and then passed to @app.route(/results/ ) where my code does some data analysis and then 1) displays some results and 2) saves some other information to JSON, which is to be used for D3 in its own @app.route(/visualization/) . Because of complications with Javascript, I want to display my D3 visualization in an iframe of its own. Right now I can load the /home/ page, type in text and hit "Submit", which then redirects me to /results/ , and prints everything correctly except the iframe . The problem is: I'm unable to get @app.route(/visualization/) to take information from my WTForm (in the same way that results is able to), so that the image can load the proper JSON file.

Here's some of my code to better illustrate the problem.

app.py :

# Home 
@app.route("/home/", methods=["GET", "POST"])
def gohome():
    error = None
    with open('somedata.pickle', 'rb')as f:
        some_content = pickle.load(f)
    try:
        if request.method == "POST":
            attempted_pmid = request.form['pmid']
    except Exception as e:
        #flash(e)
        return render_template("dashboard.html", error=error) 
    return render_template("dashboard.html", some_content=some_content)


# My WTForm for handling user-entered pmids
class pmidForm(Form):
    pmid = TextField('PubmedID')

# Results
@app.route("/results/", methods=["GET", "POST"])
def trying():
    form = pmidForm(secret_key='potato')
    try:
        if request.method == 'POST':
            entry = form.pmid.data #THIS IS THE USER INPUT FROM THE FORM #referencing 'class pmidForm'
            pmid_list = multiple_pmid_input(entry) #list for handling multiple pmids
            print(pmid_list)


            for user_input in pmid_list:
                print(str(user_input))
                user_input = str(user_input)
                # DO STUFF HERE #
                # SAVE A JSON FILE TO A FOLDER #

        return render_template('results.html')
    except Exception as e:
        return(str(e))


# Visualization
@app.route('/visualization/', methods=["GET", "POST"]) #for iframe
def visualization():
    #need to get last user_input
    form = pmidForm(secret_key='potato')
    try:
        if request.method == 'POST':
            entry = form.pmid.data 
            pmid_list = multiple_pmid_input(entry) 

            for user_input in pmid_list:
                print("This is the user input on /visualization/")
                print(str(user_input))
                user_input = str(user_input)

                #Load
                if user_input == pmid_list[-1]:
                    load_path = '/the/path/'+str(user_input)+'/'
                    completeName = os.path.join(load_path, ((str(user_input))+'.json'))
                    print(completeName)

                    with open(completeName, 'w') as load_data:
                        jsonDict = json.load(load_data)
                    print(jsonDict)
        return render_template('visualization.html', jsonDict=jsonDict)
    except Exception as e:
        return(str(e))

So as I have it now, home and results work fine together with the existing WTForm I have. I will do everything properly. But in results.html I need to load visualization.html in an iframe like so:

Line in results.html :

<iframe  id="vis1" src="https://www.website.com/visualization/" width="1000" height="1000"></iframe>

With this configuration if I run my app.py , everything displays like normal except the iframe which displays:

local variable 'jsonDict' referenced before assignment

Here, I assume that's in reference to my visualization.html which has the Jinja code:

var myjson = {{ jsonDict|tojson }};

So obviously the @app.route(/visualization/) isn't getting the information from the WTForm as it should. How can I get this second @app.route to recognize the content in the WTForm like how it works with results ?

Also, this may seem hacky, but I have very good reasons for putting my D3 in an iframe . It's because I need to be able to toggle through multiple html's like /visualization / that each have complicated Javascript that conflict with each other. The best thing I can do is isolate them all in iframe 's.

The answer is no, you can't submit one form to multiple routes or share data between multiple routes. My sollution to the problem of needing to share data between multiple routes was to create dynamic URLs. So instead of always going to a results page, it would go to results/1234 and this way I was able to access the "1234" and use it in that html.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM