I am having a problem when trying to render a SQLAlchemy query into a template, the error I get is:
TypeError: 'Users' object is not iterable
The DB is a sqlite
I have been following the "Discover Real Python" tutorial on youtube and it has been a big help. The only things i have changed is in the tutorial he uses "BlogPosts", and I use "Users"
I am trying to understand how he got users to iterate in his version of the code in the template.
My Models.py file is this:
from app import db
class Users(db.Model):
__tablename__="users"
id= db.Column(db.Integer, primary_key=True)
username=db.Column(db.String, nullable=False)
password=db.Column(db.String, nullable=False)
def __init__(self, username, password):
self.username=username
self.password=password
def __repr__(self):
return '<username{}'.format(self.username)
and my "app.py" file.
from flask import Flask, render_template, redirect, url_for, request, session, flash
from functools import wraps
#import sqlite3
from flask.ext.sqlalchemy import SQLAlchemy
app= Flask(__name__)
app.secret_key="this is the secret key"
#app.database="users.db"
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:////users2.db'
db=SQLAlchemy(app)
from models import *
def login_required(f):
@wraps(f)
def wrap(*args, **kwargs):
if 'logged_in' in session:
return f(*args, **kwargs)
else:
flash('You must be logged in to complete this action')
return redirect(url_for('login'))
return wrap
@app.route('/')
def index():
users= db.session.query(Users).all()
return render_template('index.html', users=users)
@app.route('/testing')
def testing():
users= db.session.query(Users).all()
return render_template('testquery.html', users=users)
@app.route('/welcome')
def welcome():
return render_template('index.html')
@app.route('/login', methods =['GET', 'POST'])
def login():
error= None
#form = LoginForm(request.form)
if request.method == 'POST':
#if request.form.validate_on_submit():
if request.form['username'] !='admin' or request.form['password'] !='admin':
error= 'invalid credentials'
else:
session ['logged_in']=True
flash('login successful')
return redirect(url_for('loggedin'))
#else:
#render_template('login.html', form=form, error=error)
return render_template('login.html', error=error)
@app.route('/loggedin')
@login_required
def loggedin():
return render_template('loggedin.html')
@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You have been logged out')
return redirect(url_for('welcome'))
#def connect_db():
# return sqlite3.connect(app.database)
if __name__=='__main__':
app.run(debug=True)
The method I have been using to text is the route of "/testing", the testquery.html file is what I have been trying to test with, and have been getting the error with.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<table>
{%for user in users%}
<tr>
<td>{{user.username}}</td>
<td>{{user.password}}</td>
</tr>
</table>
{%endfor%}
</body>
</html>
I tried the fix i saw in another stack question:
def __init__(self, username, password):
self.username=[username]
self.password=[password]
To no avail, this changed nothing. Anyone have any idea what I need to do to make it iterable.