2

I am working on an assignment for a Flask application with a function that does different things based on the value of a hidden field in a form on the index.html page. I am to have only two routes: '/' (index.html) and '/process' (which performs actions on index.html).

When I run this in Flask (python server.py in a virtualenv), and click the button "Make Money" on index.html, I get this error:

"TypeError TypeError: 'ImmutableMultiDict' object is not callable"

Can someone please tell me how I can get the desired value from the hidden input?

contents of server.py

import datetime
import random
from flask import Flask, render_template, redirect, request, session

app = Flask(__name__)
app.secret_key = 'fooBarBaz'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/process', methods=['GET','POST'])
def process():
    if request.method == 'POST':
        target = request.form('name')
        if target == 'clothing':
            new_money = random.randrange(10, 21)
            session['balance'] += new_money
            timestamp = datetime.datetime.now()
            session['register'] += ("Received" + new_money + " dollars at " + timestamp.strftime("%Y/%m/%d %I:%M %p")) 
        return render_template('index.html')

app.run(debug=True)

contents of index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div container>
        <div class='balance'>
            <p>Your balance:  {{ session['balance'] }}</p>
        </div>
        <div class="shops">
            <div class="clothing">
                <h2>Clothing Store</h2>
                <p>(earns 10 - 20 dollars)</p>
                <form action="/process" method="post">
                    <input type="hidden" name="clothing">
                    <input type="submit" value="Make Money!">
                </form>
            </div> 
        </div> 
        <div class="register">
            <h4>Receipt Tape</h4>
            <p>{{ session['register'] }}</p>
        </div>
    </div>
</body>
</html>
2
  • 1
    target = request.form('name') cannot work, just use brackets instead. but you don't have any input named "name", should it be clothing maybe ? Commented Jun 16, 2018 at 20:55
  • 1
    btw, you may facing another issue with session['balance'] += new_money, if session['balance'] is not declared before, you cannot use this operator Commented Jun 16, 2018 at 20:58

1 Answer 1

4

The form should be something like below, with a value defined for the hidden input:

<form action="/process" method="post">
    <input type="hidden" name="clothing" value="clothing">
    <input type="submit" value="Make Money!">
</form>

Without changing the logic too much, the register section could accept html tags to render linebreaks

<p>{{ session['register']|safe }}</p>

Then with minimal changes, this is how you could resolve some issues you are facing in the view. To avoid error about session key not declared, the best way is to used the method get with 0, or "" instead of the None returned when the key is not found:

@app.route('/process', methods=['GET','POST'])
def process():

    if request.method == 'POST':
        target = request.form.get('clothing')
        if target == 'clothing':
            new_money = random.randrange(10, 21)
            session['balance'] = session.get('balance',0) + new_money
            timestamp = datetime.datetime.now()
            session['register'] = "{}<br>Received {} dollars at {}".format(
                session.get('register',''),
                new_money,
                timestamp.strftime("%Y/%m/%d %I:%M %p"))
        return render_template('index.html')
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.