Я застрял на этом некоторое время.Это если к 2019 году псет8 финансов.Ошибка в check50 говорит, что моя страница регистрации не включает в себя все элементы.Ошибка на cs50.me говорит, что макет не определен.Я перепроверил свой код несколько раз и не могу найти, где находится ошибка.
Вот код ошибки:
:( страница регистрации содержит все необходимые элементы, приложение вызвало исключение (перезапустите с -журнал для более подробной информации) Журнал отправки GET-запроса / зарегистрировать исключение, возникшее в приложении: UndefinedError: 'layout' не определено
Вот мой код:
from cs50 import SQL
from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash
from helpers import apology, login_required, lookup, usd
# Configure application
app = Flask(__name__)
# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True
# Ensure responses aren't cached
@app.after_request
def after_request(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response
\
# Custom filter
app.jinja_env.filters["usd"] = usd
# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Configure CS50 Library to use SQLite database
db = SQL("sqlite:///finance.db")
# Make sure API key is set
if not os.environ.get("API_KEY"):
raise RuntimeError("API_KEY not set")
@app.route("/")
@login_required
def index():
"""Show portfolio of stocks"""
# Lookup User
users = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id=session["user_id"])
stocks = db.execute(\
"SELECT symbol, SUM(shares) as total_shares FROM transactions WHERE user_id = :user_id GROUP BY symbol HAVING total_shares > 0", user_id=session["user_id"])
quotes = {}
for stock in stocks:
quotes[stock['symbol']] = lookup(stock['symbol'])
cash_left = users[0]['cash']
total = cash_left
return render_template("portfolio.html", quotes=quotes, stocks=stocks, total=total, cash_left=cash_left)
\
@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
"""Buy shares of stock"""
if request.method == "POST":
stock = lookup(request.form.get("symbol"))
if stock == None:
return apology("Invalid Symbol")
# Check for positive integer
try:
shares = int(request.form.get("shares"))
except:
return apology("Shares must be a number")
# Check if requested 0 shares
if shares <= 0:
return apology("Cannot buy 0 or negative shares")
# Get username from database
rows = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id=session["user_id"])
# Check account balance
cash_left = rows[0]['cash']
price_share = stock['price']
# Calculate total price
total_price = price_share * shares
if total_price > cash_left:
return apology("Insufficient Funds")
# Execute Purchase
db.execute("UPDATE users SET cash = cash - :price WHERE id = :user_id", price=total_price, user_id=session["user_id"])
db.execute("INSERT INTO transactions (user_id, symbol, shares, price_share) VALUES(:user_id, :symbol, :shares, :price)",\
user_id=session["user_id"], symbol=request.form.get("symbol"), shares=shares, price=price_share)
flash("Purchase Complete")
return redirect("/")
else:
return render_template("buy.html")
@app.route("/check", methods=["GET"])
def check():
"""Return true if username available, else false, in JSON format"""
username = request.form.get("username")
if (len(username) > 0) or (len(db.execute("SELECT * FROM users WHERE username = :username", username=username)) == 0):
return jsonify(True)
else:
return jsonify(False)
\
@app.route("/history")
@login_required
def history():
"""Show history of transactions"""
transactions = db.execute(\
"SELECT symbol, shares, price_share, created_at FROM transactions WHERE user_id = :user_id ORDER BY created_at ASC", user_id=session["user_id"])
return render_template("history.html", tansactions=transactions)
\
@app.route("/add", methods=["GET", "POST"])
@login_required
def add():
"""Allow User to Add Funds"""
if request.method == "POST":
try:
amount = float(request.form.get("amount"))
except:
return apology("Must enter a valid amount")
db.execute("UPDATE users SET cash = cash + :amount WHERE id = :user_id", user_id=session["user_id"], amount=amount)
return redirect("/")
else:
return render_template("add.html")
\
@app.route("/login", methods=["GET", "POST"])
def login():
"""Log user in"""
# Forget any user_id
session.clear()
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure username was submitted
if not request.form.get("username"):
return apology("must provide username", 403)
# Ensure password was submitted
elif not request.form.get("password"):
return apology("must provide password", 403)
# Query database for username
rows = db.execute("SELECT * FROM users WHERE username = :username",
username=request.form.get("username"))
# Ensure username exists and password is correct
if len(rows) != 1 or not check_password_hash(rows[0]["hash"], request.form.get("password")):
return apology("invalid username and/or password", 403)
# Remember which user has logged in
session["user_id"] = rows[0]["id"]
# Redirect user to home page
return redirect("/")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("login.html")
@app.route("/logout")
def logout():
"""Log user out"""
# Forget any user_id
session.clear()
# Redirect user to login form
return redirect("/")
@app.route("/quote", methods=["GET", "POST"])
@login_required
def quote():
"""Get stock quote."""
if request.method == "POST":
quote = lookup(request.form.get("symbol"))
if not quote:
return apology("Invalid Symbol")
return render_template("quoted.html", quote=quote)
else:
return render_template("quote.html")
@app.route("/register", methods=["GET", "POST"])
def register():
"""Register user"""
if request.method == "POST":
# Username Submission
if not request.form.get("username"):
return apology("Please enter username")
# Password Submission
elif not request.form.get("password"):
return apology("Please enter password")
elif not request.form.get("confirmation"):
return apology("Please enter password")
# Passwords Match
elif request.form.get("password") != request.form.get("confirmation"):
return apology("Passwords do not match")
# Enter user into database
hash = generate_password_hash(request.form.get("password"))
input = db.execute("INSERT INTO users (username, hash) VALUES(:username, :hash)",\
username = request.form.get("username"), hash=hash)
# Register and Re-direct
if not input:
return apology("Username already take, please choose a different username")
rows = db.execute("SELECT * FROM users WHERE username = :username", username=request.form.get("username"))
session["user_id"] = input
flash("Registered")
return redirect("/")
else:
return render_template("register.html")
@app.route("/sell", methods=["GET", "POST"])
@login_required
def sell():
"""Sell shares of stock"""
if request.method == "POST":
quote = lookup(request.form.get("symbol"))
if not quote:
return apology("Invalid Symbol")
# Check for positive integer
try:
shares = int(request.form.get("shares"))
except:
return apology("Shares must be a positive number")
# Check if requested 0 shares
if shares <= 0:
return apology("Cannot buy 0 shares")
# Check for # of shares
stock = db.execute("SELECT SUM(shares) as total_shares FROM transactions WHERE id = :user_id AND symbol = :symbol GROUP BY symbol",\
user_id=session["user_id"], symbol=request.form.get("symbol"))
if not user_shares or int(user_shares[0]["shares"]) < shares:
return apology("Insufficient number of shares")
# Get username from database
rows = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id=session["user_id"])
# Check account balance
cash_left = rows[0]['cash']
price_share = quote['price']
# Calculate total price
total_price = price_share * shares
# Execute Sale
db.execute("UPDATE users SET cash = cash + :price WHERE id = :user_id", price=total_price, user_id=session["user_id"])
db.execute("INSERT INTO transactions (user_id, symbol, shares, price_share) VALUES(:user_id, :symbol, :shares, :price)",\
user_id=session["user_id"], symbol=request.form.get("symbol"), shares=shares, price=price_share)
flash("Sale Complete")
return redirect("/")
else:
stocks = db.execute(\
"SELECT symbol, SUM(shares) as total_shares FROM transactions WHERE id = :user_id GROUP BY symbol HAVING total_shares > 0", user_id=session["user_id"])
return render_template("sell.html", stocks=stocks)
def errorhandler(e):
"""Handle error"""
if not isinstance(e, HTTPException):
e = InternalServerError()
return apology(e.name, e.code)
# Listen for errors
for code in default_exceptions:
app.errorhandler(code)(errorhandler)
Вот мой register.html
{% block title %}
Register
{% endblock %}
{% block main %}
<form action="/register" method="post">
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" type="text">
</div>
<div class="form-group">
<input class="form-control" name="password" placeholder="Password" type="password">
</div>
<div class="form-group">
<input class="form-control" name="confirmation" placeholder="Password (again)" type="password">
</div>
<button class="btn btn-primary" type="submit">Register</button>
</form>
{% endblock %}