For the life of me I cannot get my index page to properly display the data from my database. I have tried multiple methods and research on several sites. I'm thinking it is something right in front of my face, but right now I can't see the forest through the trees. I have included my code below.
Application:
#app.route("/")
#login_required
def index():
users = db.execute("SELECT * FROM users WHERE id = :user_id", user_id=session["user_id"])
stocks = db.execute("SELECT * FROM transactions WHERE id = :user_id", user_id=session["user_id"])
quotes = {}
for symbol in stocks:
quotes[symbol["symbol"]] = lookup(symbol["symbol"])
return render_template ("index.html", quotes=quotes,stocks=stocks, symbol=symbol)
index.html:
{% extends "layout.html" %}
{% block title %}
Portfolio
{% endblock %}
{% block main %}
<table class="table table-striped">
<tr>
<th> Symbol</th>
<th> Current Share Price</th>
<th> Shares Owned</th>
<th> Shares Owned Value</th>
</tr>
{% for stock in stocks %}
<tr>
<td>{{symbol.symbol}}</td>
<td>{{quotes[stock.symbol]["price"] | usd }}</td>
<td>{{symbol.shares}}</td>
<td>{{symbol.total_price}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Finally here is a screenshot of my index.html as it generates now:
And the data in my database table:
As you can see, the table displays the symbol, shares and total price from only one of the transactions. It shows the correct updated price for each stock, but I can't get it to pull the correct data from the table. Thank you so much for any help.
symbol has the value of the last iteration of for symbol in stocks:. Looks like the html should be creating the td elements from stock ({% for stock in stocks %}) not from symbol.
Suggestion to simplify:
In the for symbol in stocks: loop in the .py, add a key to the symbol dictionary for price. That would render the quotes object unnecessary and the stocks list would be self contained.
Related
I am trying to display a portfolio of stocks. The task is to access the database and then to lookup for the current price of the stock, displaying it, the total value of the stocks, the remaining cash from 10000 and the grand total, that should be changing depending on the current stock price.
I have tried various ways to access and display data but I am constantly having errors and I need a help, please. I have also tried to create a for loop and to append data to list but again without success.
The error is:
File "/home/ubuntu/finance/application.py", line 58, in index
current_price=lookup(row["symbol"]["price"])
TypeError: 'NoneType' object is not subscriptable
My code is below:
#app.route("/")
#login_required
def index():
"""Show portfolio of stocks"""
#Access the stocks of the current user from DB
rows=db.execute("SELECT symbol, name, sum(shares) as shares FROM stocks WHERE user_id=:user_id ORDER BY symbol", user_id=session["user_id"])
#Check the current price of each stock using the helper function lookup and calculate the total cost of each stock( * number of shares by price)
#add that info to rows and render it on the index page
sum_total_cost=0
for row in rows:
#symbol=row["symbol"]
#current_price=lookup(symbol["price"])
current_price=lookup(row["symbol"]["price"])
total_cost=current_price*(row["shares"])
row["current_price"]=usd(current_price)
row["total_cost"]=usd(total_cost)
sum_total_cost+=total_cost
#Check the current cash of the user
user_id=session["user_id"]
user = db.execute("SELECT cash FROM users WHERE id=:user_id", user_id=user_id)
cash=user[0]["cash"]
grand_total = cash+sum_total_cost
return render_template("index.html", rows=rows, cash = cash, grand_total=grand_total)
And HTML
{% extends "layout.html" %}
{% block title %}
Index
{% endblock %}
{% block main %}
<h2>Portfolio</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Symbol</th>
<th>Name</th>
<th>Shares</th>
<th>Price</th>
<th>Total Cost</th>
</tr>
</thead>
<tbody>
<!-- TODO: Loop through the database to display all transactions and the balance -->
{% for row in rows %}
<tr>
<td>{{row.symbol}}
<td>{{row.name}}</td>
<td>{{row.shares}}</td>
<td>{{row.current_price}}</td>
<td>{{row.total_cost}}</td>
{% endfor %}
</tr>
<tr>
<th>Cash</th>
<td></td>
<td></td>
<td></td>
<td>{{cash}}</td>
</tr>
<tr>
<th>Grand Total</th>
<td></td>
<td></td>
<td></td>
<td>{{grand_total}}</td>
</tr>
</tbody>
</table>
</div>
</div>
{% endblock %}
Lookup function
def lookup(symbol):
"""Look up quote for symbol."""
# Contact API
try:
api_key = os.environ.get("API_KEY")
url = f"https://cloud-sse.iexapis.com/stable/stock/{urllib.parse.quote_plus(symbol)}/quote?token={api_key}"
response = requests.get(url)
response.raise_for_status()
except requests.RequestException:
return None
# Parse response
try:
quote = response.json()
return {
"name": quote["companyName"],
"price": float(quote["latestPrice"]),
"symbol": quote["symbol"]
}
except (KeyError, TypeError, ValueError):
return None
The error message is self-explanatory, it should be that line that is causing the problem:
current_price=lookup(row["symbol"]["price"])
Since you are reading from a table you should very likely be using row["symbol"], possibly transformed by some operation. You are addressing the field as if it were a dict. I don't know what your lookup does though. I would guess it takes just one argument so it could simply be something like that: current_price=lookup(row["symbol"])
Perhaps post the code for the lookup function if you don't manage to fix the issue.
PS: maybe the whole calculation could be done in SQL, probably a matter of JOINing two tables or something.
I'm working on a project that pulls a list of all the spirits listed in the Oregon State liquor pricing sheet and stores it in a table in my flask app. The goal is to be able to let moderators see the list and check a box next to each spirit to designate if it is whiskey or not.
It's my first time really using flask, but I've gone through a book about flask twice now to try and understand it, so this is me trying to build my own thing.
Right now, if I check a box and then hit submit all the records are switched to is_whiskey = False instead of each one being done individually.
Here's my model:
class Whiskies(db.Model):
__tablename__ = 'whiskies'
id = db.Column(db.Integer, primary_key=True)
ols_name = db.Column(db.String(64), unique=True)
display_name = db.Column(db.String(64), unique=True, index=True)
display_distiller = db.Column(db.String(64), unique=False)
is_whiskey = db.Column(db.Boolean, default=True)
reviews = db.relationship('Review', backref='review', lazy='dynamic')
Here's my view:
#main.route('/update-whiskies', methods=['GET', 'POST'])
#login_required
#permission_required(Permission.MODERATE)
def update_whiskies():
whiskies = Whiskies.query.all()
is_whiskey_form = IsWhiskeyForm()
submitpageform = SubmitPageForm()
if submitpageform.validate_on_submit():
for w in whiskies:
w.is_whiskey = is_whiskey_form.is_whiskey.data
db.session.update(w)
db.session.commit()
flash("You updated a bunch of whiskies")
return redirect(url_for('.index'))
return render_template('update_whiskies.html', whiskies=whiskies,
is_whiskey_form=is_whiskey_form,
submitpageform=submitpageform)
Here's my .html page:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block page_content %}
<div>
{% for whiskey in whiskies %}
<li class="whiskey">
{% if whiskey.display_name %}
{{ whiskey.display_name }}
{% else %}
{{ whiskey.ols_name }}
{% endif %}
{{ is_whiskey_form.is_whiskey.label }}
{{ is_whiskey_form.is_whiskey(value=whiskey.is_whiskey) }}
</li>
{% endfor %}
{{ wtf.quick_form(submitpageform) }}
</div>
{% endblock %}
Here are my forms:
class IsWhiskeyForm(Form):
"This is intended for use in bulk editing whiskies"
is_whiskey = BooleanField("Is Whiskey", default="checked")
class SubmitPageForm(FlaskForm):
"This is intended for submitting a batch edit"
submit = SubmitField('Update Whiskies')
This is what the page currently looks like. I want to be able to check a box and hit submit and then have it reflected in the db.
Thanks a lot to whoever is up to helping me with this. I've been stuck about a week and I just need to get past this hump to finish up my module.
I had a similar task to solve: producing a list of database records (1 record per row) and let the user choose one record. So I put a radiobox at the end of each row. The problem was how to inform the Flask app which row was checked. I came up with the following solution:
You must make the submit button of the form trigger a POST request
You need in the data you want to show in the browser one field which is unique so you can use it to identify a row (I had data from an SQL database to display, so the primary key of a record was a good solution)
Add a radiobutton in your html-template inside the {% for ... %} loop like this:
{% for data in dataset.items %}
... display the data of the row, plus:
<div>
<input type="radio" class="form-check-input cursor-pointer"
name="check_line" value="{{ data._id }}">
</div>
{% endfor %}
in the POST request data there will appear a name-value pair produced by the radiobuttons which consists of the name you provided (here: "check_line") and the value you provided. The trick is that the value can be used to identify the row (is unique) because the Flask-rendering-magic was used.
By the way: when testing POST-requests I often write:
if request.method == 'POST':
print(request.values)
in the route-functions where POST needs to be handled. This will display all the POST input parameters on the Flask-console.
Try this
if submitpageform.validate_on_submit():
for w in whiskies:
w.is_whiskey = is_whiskey_form.is_whiskey.data
db.session.commit()
Remove db.session.update(w)
I'm working on the index portion of the finance pset. I can't get the stock information to show up in the html table. I'm having a difficult time thinking how to loop through the stock information without having to create a new dictionary with the new data. Could someone help me with this direction that I'm taking? And can someone give me a "better" approach? I feel like this is not the "best" way to solve this problem. Hopefully the code appears correctly, I'm still learning how to use this site.
#app.route("/") #login_required def index():
"""Show portfolio of stocks"""
#set portfolio GROUPED BY symbol
portfolio = db.execute("SELECT symbol, SUM(shares) AS share_total FROM portfolio WHERE user_id = :user_id GROUP BY symbol", user_id = session["user_id"])
row = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id = session["user_id"])
remaining_cash = row[0]["cash"]
total_holding_value = 0
stock_info = {}
for stock in portfolio:
symbol = stock["symbol"]
shares = stock["share_total"]
quote = lookup(symbol)
price = quote["price"]
holding_value = shares * price
total_holding_value += holding_value
stock_info.update({"symbol":symbol, "shares":shares, "price":price, "holding_value":holding_value})
grand_total = total_holding_value + remaining_cash
return render_template("index.html", stock_info = stock_info, remaining_cash = remaining_cash, grand_total = grand_total)
{% extends "layout.html" %}
{% block title %}
Portfolio
{% endblock %}
{% block main %}
<table class="table table-bordered">
<thead>
<th>Symbol</th>
<th>Shares</th>
<th>Price</th>
<th>Total</th>
</thead>
<tbody>
{% for stock in stock_info %}
<tr>
<td>{{ stock.symbol }}</td>
<td>{{ stock.shares }}</td>
<td>{{ stock.price }}</td>
<td>{{ stock.holding_value }}</td>
</tr>
{% endfor %}
<tr>
<td></td>
<td></td>
<td>Remaining Balance:</td>
<td>{{ remaining_cash }}</td>
</tr>
<tr>
<td></td>
<td></td>
<td>Grand Total:</td>
<td>{{ grand_total }}</td>
</tr>
</tbody>
</table>
{% endblock %}
One problem is here stock_info.update({"symbol":symbol, "shares":shares, "price":price, "holding_value":holding_value}). From the python doc [empashis added].
update([other])
Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.
Chances are you want to send a list of dictionaries to the html. Consider declaring stock_info a list, and using the append method to add each stock.
I'm using Jinja2 Template to change dynamically a result table for my Motor Racing webapp. It's not perfect, but I'm making my way with patience.
I have a template that is rendered by the URL 'webapp.com/driver/' that's supposed to show the results of a Race where the driver was present inside a table. To make it clear:
The user selects a Driver and goes to webapp.com/driver/someDriver
The someDriver page has a dropdown list with ALL Races the someDriver has been through
User selects someRace from dropdown list
Table is fed by someRace's results
The python flask route I wrote for it:
#app.route('/driver/<driverid>')
def driver(driverid):
driver = db.Drivers.find_one({'_id': ObjectId(driverid)})
races = db.Races.find({'finalresult.driver':driver['unique_name']}).sort([('timestamp', -1)])
racesList = []
for race in races:
raceItem = {
'filename':race['filename'],
'date':datetime.datetime.fromtimestamp(float(race['timestamp'])).strftime('%d-%m-%Y'),
'finalresult':race['finalresult'],
'id':str(race['_id'])}
racesList.append(raceItem)
return render_template('user.html', driver=driver, racesList=racesList)
Now I'm trying to make a dynamic template that changes the Result table everytime the user change the selection.
<div class="row">
<form name="racesForm">
<label for="selRace">Escolha uma corrida!</label>
<select class="form-control" id="selRace">
{% for race in racesList %}
<option value="{{race.filename}}">
{{race.filename}}
</option>
{% endfor %}
</select>
</form>
<hr>
</div>
<div class="row">
<table>
<thead>
<th>Position</th>
<th>Driver</th>
</thead>
<tbody>
<tr>
{% position, drivername in race.finalresult %}
<th>{{position}}</th>
<td>{{drivername}}</td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
But now I'm receiving a error:
Encountered unknown tag 'position'.
And that's it..I'm not sure of how to make this dropdown list change the table dynamically. Any insights 'd be aprecciated.
UPDATE//Giving more info:
Driver is a very simples dict/json that has two keys ['name'] and ['_id']
racesList is an array of many "raceItem"s.
Each "raceItem" has a key anmed 'finalresult' that has data of the positions each driver has finished.
this array is filled with many objects it may seem like the example below:
'finalresult': [
{'position': 1,
'drivername': 'John Doe'},
'position': 2,
'drivername': 'Foo Bazz', etc
}]
As I told before, I want this data to be displayed in a table, depending on what RACE has been selected from the "raceList" dropdown list.
As a solution, I'm thinking of creating a new routing...but I wanted this routing to be displayed in the same page. I don't want the user to be directed to a new window.
First of all, you are getting Encountered unknown tag 'position' as you are using a different data structure. As you mentioned finalresult is a list of dicts. So you need to iterate through it when populating your table.
{% for driver_stat in race.finalresult %}
<td>{{driver_stat.position}}</td>
<td>{{driver_stat.drivername}}</td>
{% endfor %}
But with your approach, this table will not be updated dynamically as you select different race from your dropdown. Instead I suggest to use jquery. So you don't have to nevigate to another page to display the driver stats. I found several useful SO question that have been already answered on this. Follow them.
Ref:
Populate table based in select
Populate HTML table based on second dropdown selection
I have a custom macro method that returns a string array of field names whose values I want to output in a Text/XML transformation. The transformation is being used as the Item Template in a Datalist. I cannot figure out though how to dynamically get the value from the current data item. It seems that DataItem does not resolve -- nothing outputs from the GetValue call below. Using CurrentDocument would obviously resolve the page instead of the data item.
<tr>
<td>{% SKUNumber %}</td>
{% foreach (spec in Util.GetSpecFieldsForPageType(CurrentDocument.NodeClass, "RelatedModelsTable")) { %}
<td class="hidden-xs">{% GetValue(DataItem, spec) %} </td>
{% } #%}
</tr>
Is there any way to access the current data item in a Text/XML transformation? Or do I need to switch to an ASCX transform?
Assuming you're using Kentico v10, you're looking for the Object macro.
Using an indexer, you can specify a column to retrieve data from:
{% Object[columnName] %}
In your case, it would be:
<tr>
<td>{% SKUNumber %}</td>
{% foreach (spec in Util.GetSpecFieldsForPageType(CurrentDocument.NodeClass, "RelatedModelsTable")) { %}
<td class="hidden-xs">{% Object[spec] %}</td>
{% } #%}
</tr>
Here's a generic example, for those who need an example without any custom macros. This will dynamically render DocumentID, DocumentName and NodeAliasPath, specifying the columns in an array, as opposed to hardcoding them.
<tr>
{% columns = "DocumentID,DocumentName,NodeAliasPath"; foreach (column in columns.Split(",")) { %}
<td>{% Object[column] %} </td>
{% } #%}
</tr>
EDIT:
As Kentico v9 does not have the Object macro for transformations, one way to dynamically resolve a value of the repeated item is to use Util.ResolveMacroExpession, and supply the column name as the parameter.
The repeated item fields are registered as named sources, so there is no way to access them with an indexer or macro method.
Here's the same example from the question author, modified to work in Kentico v9:
<tr>
<td>{% SKUNumber %}</td>
{% foreach (spec in Util.GetSpecFieldsForPageType(CurrentDocument.NodeClass, "RelatedModelsTable")) { %}
<td class="hidden-xs">{% Util.ResolveMacroExpression(spec) %}</td>
{% } #%}
</tr>
You have to give us the scenario to get the right answer
If your {% Util.GetSpecFieldsForPageType(CurrentDocument.NodeClass, "RelatedModelsTable")%} returns IEnumbrable you can use ApplyTransformation