App.route doesn't work in Flask for one method - python

Here's my code:
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app._static_folder = 'static/'
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:test#localhost/Scheduling'
db = SQLAlchemy(app)
class CPR_INFO(db.Model):
DEAL_ID = db.Column(db.String(50), primary_key=True)
POG_NUM = db.Column(db.String(50))
OPOG_START_DT = db.Column(db.Date())
OPOG_END_DT = db.Column(db.Date())
def __repr__(self):
return 'Deal_ID ' + str(self.DEAL_ID)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/posts', methods=['GET', 'POST'])
def posts():
if request.method == 'POST':
post_id = request.form['DEAL_ID']
post_title = request.form['POG_NUM']
post_content = request.form['OPOG_START_DT']
new_post = CPR_INFO(DEAL_ID = post_id, POG_NUM=post_title, OPOG_START_DT=post_content)
db.session.add(new_post)
db.session.commit()
return redirect('/posts')
else:
all_posts = CPR_INFO.query.all()
return render_template('posts-2.html', posts=all_posts)
#app.route('/posts/new', methods = ['GET', 'POST'])
def new_post():
if request.method == 'POST':
post_id = request.form['DEAL_ID']
post_title = request.form['POG_NUM']
post_content = request.form['OPOG_START_DT']
new_post = CPR_INFO(DEAL_ID=post_id, POG_NUM=post_title, OPOG_START_DT=post_content)
db.session.add(new_post)
db.session.commit()
return render_template('posts-2.html', posts=all_posts)
else:
return render_template('new_post_2.html')
#app.route('/posts/delete/<string:DEAL_ID>')
def delete(DEAL_ID):
post = CPR_INFO.query.get_or_404(DEAL_ID)
db.session.delete(post)
db.session.commit()
return redirect('/posts')
#app.route('/posts/edit/<string:DEAL_ID>', methods = ['GET', 'POST'])
def edit(DEAL_ID):
post = CPR_INFO.query.get_or_404(DEAL_ID)
if request.method == 'POST':
post.DEAL_ID = request.form['DEAL_ID']
post.POG_NUM = request.form['POG_NUM']
post.OPOG_START_DT = request.form['OPOG_START_DT']
db.session.commit()
return redirect('/posts')
else:
return render_template('edit-2.html', post = post)
if __name__ == "__main__":
app.run(debug=True)
This part of my code fails. The URL is not rendered because the DEAL_ID is not read:
#app.route('/posts/delete/<string:DEAL_ID>')
def delete(DEAL_ID):
post = CPR_INFO.query.get_or_404(DEAL_ID)
db.session.delete(post)
db.session.commit()
return redirect('/posts')
I get the following error message on my HTML page:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

Add methods parameter at your #app.route('/posts/delete/<string:DEAL_ID>')

Related

Why i am getting UnboundLocalError in Flask?

this is my app.py code but i am receiving unbound local error after adding another path for delete and creating the function delete.
from crypt import methods
from email.policy import default
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Todo(db.Model):
sno = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
desc = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self) -> str:
return f"{self.sno} - {self.title}"
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)
#app.route('/delete/<int:sno>')
def delete(sno):
todo = Todo.query.filter_by(sno==sno).first()
db.session.delete(todo)
db.session.commit()
return redirect('/')
if __name__ == "__main__":
app.run(debug=True, port=8000)
Below i've added the screenshot of the errors i am getting even when i just visit the root url.
Problem
If the server receive a GET /, then you won't define te title variable, but would try to use it at Todo(title=title, desc=desc) so an error
Fix
All the creation code should be in the if POST branch
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)

AttributeError: 'scoped_session' object has no attribute 'get'

I am trying to delete data from my database but my web application returns this error:
File "C:\Users\q\Pyc\Flask\basic_of_flask\SQL Database with flask\Database in view\adoption_sit.py", line 78, in del_pup
pup = db.session.get(id)
AttributeError: 'scoped_session' object has no attribute 'get'
have a look at my code below
import os
from flask import Flask, redirect, render_template, url_for
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from form import AddForm, DelForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'
#######################################
#### SQL DATABASE SECTION #############
#######################################
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
Migrate(app, db)
########################################
######## Models ########################
########################################
class Puppy(db.Model):
__tablename__ = 'puppies'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text)
def __init__(self, name):
self.name = name
def __repr__(self):
return f"Puppy name is {self.name}."
#############################################
##### VIEW FUNCTIONS -- HAVE FORM ###########
#############################################
#app.route('/')
def index():
return render_template('home.html')
#app.route('/add', methods=['GET', 'POST'])
def add_pup():
form = AddForm()
if form.validate_on_submit():
name = form.name.data
new_puppy = Puppy(name)
db.session.add(new_puppy)
db.session.commit()
return redirect(url_for('list_pup'))
return render_template('add.html', form=form)
#app.route('/list_pup')
def list_pup():
puppies = Puppy.query.all()
return render_template('list.html', puppies=puppies)
#app.route('/delete', methods=['GET', 'POST'])
def del_pup():
form = DelForm()
if form.validate_on_submit():
id = form.id.data
pup = db.session.get(id)
db.session.delete(pup)
db.session.commit()
return redirect(url_for('list_pup'))
return render_template('delete.html', form=form)
db.create_all()
if __name__ == '__main__':
app.run(debug=True)
and here is my form.py file
# form.py
from flask_wtf import FlaskForm
from wtforms import SubmitField, StringField, IntegerField
class AddForm(FlaskForm):
name = StringField('Name of puppy:')
submit = SubmitField('Submit puppy')
class DelForm(FlaskForm):
id = IntegerField("Id number of puppy to be remove:")
submit = SubmitField("Remove puppy")
i guess you are doing things the wrong way in del_pup() function
[..]
pup = db.session.get(id) # here
you need to get the Puppy object with the given id like:
#app.route('/delete', methods=['GET', 'POST'])
def del_pup():
form = DelForm()
if form.validate_on_submit():
id = form.id.data
# pup = db.session.get(id) # wrong way
pup = Puppy.query.filter_by(id=id).first()` # here
db.session.delete(pup)
db.session.commit()
return redirect(url_for('list_pup'))
return render_template('delete.html', form=form)

ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'FileStorage'

I just want to write a filename from data to my model.
How to get filename from filestorage?
I'm using Flask for my web app. I create form that include FileField.
It is important for me to get the same filename.
Form:
class TableForm(FlaskForm):
file = FileField('Add file', validators=[FileAllowed(['xlsx', 'xls', 'csv'])])
submit = SubmitField('Add file')
Model:
class Table(db.Model):
__table_args__= {'schema': 'app'}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(240), nullable=False)
table_file = db.Column(db.String(80), nullable=False)
Routes:
#app.route("/projects/<int:project_id>", methods=['GET', 'POST'])
#login_required
def project_data_source(project_id):
tables = Table.query.filter_by(project_id=project_id)
if project.author != current_user:
abort(403)
form = TableForm()
if form.validate_on_submit():
table = Table(name=form.file.data, table_file=form.file.data)
db.session.add(table)
db.session.commit()
return redirect(url_for('project_data_source'))
There's a pretty good example on their docs. Here's how you get the file name:
from werkzeug.utils import secure_filename
f = form.file.data
filename = secure_filename(f.filename)
So your code would need to be:
from werkzeug.utils import secure_filename
#app.route("/projects/<int:project_id>", methods=['GET', 'POST'])
#login_required
def project_data_source(project_id):
tables = Table.query.filter_by(project_id=project_id)
if project.author != current_user:
abort(403)
form = TableForm()
if form.validate_on_submit():
filename = secure_filename(form.file.data.filename)
table = Table(name=filename, table_file=filename) # not sure why you save it twice here
db.session.add(table)
db.session.commit()
return redirect(url_for('project_data_source'))

DataError: (psycopg2.DataError) invalid input syntax for integer

I'm trying to add Flask-Login to my Flask-Python app but I'm having this error and I don't know why.
I guess thats my user.loader that isnt correct but the idea is to load the user based on the ID or email.
Any idea what am I doing wrong?
Thanks in advance
Regards
full error :
DataError: (psycopg2.DataError) invalid input syntax for integer:
"t#t.pt" LINE 3: WHERE users.uid = 't#t.pt'
app.py
from flask import Flask, render_template, request, session, redirect, url_for
from models import db, User
from forms import SignupForm, LoginForm
from flask_login import LoginManager, UserMixin, \
login_required, login_user, logout_user
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/polex'
db.init_app(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
app.secret_key = "development-key"
#login_manager.user_loader
def user_loader(uid):
"""Given *user_id*, return the associated User object.
:param unicode user_id: user_id (email) user to retrieve
"""
return User.query.get(uid)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/about")
def about():
return render_template("about.html")
#app.route("/signup", methods=["GET", "POST"])
def signup():
if 'email' in session:
return redirect(url_for('home'))
form = SignupForm()
if request.method == "POST":
if form.validate() == False:
return render_template('signup.html', form=form)
else:
newuser = User(form.first_name.data, form.last_name.data, form.email.data, form.password.data)
db.session.add(newuser)
db.session.commit()
session['email'] = newuser.email
return redirect(url_for('home'))
elif request.method == "GET":
return render_template('signup.html', form=form)
#app.route("/login", methods=["GET", "POST"])
def login():
print db
form = LoginForm()
if request.method == "POST":
if form.validate() == False:
return render_template("login.html", form=form)
else:
email = form.email.data
password = form.password.data
user = User.query.filter_by(email=email).first()
if user is not None and user.check_password(password):
login_user(user, remember=True)
return redirect(url_for('home'))
else:
return redirect(url_for('login'))
elif request.method == 'GET':
return render_template('login.html', form=form)
#app.route("/logout")
def logout():
session.pop('email', None)
return redirect(url_for('index'))
#app.route("/home", methods=["GET", "POST"])
def home():
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True)
models.py
from flask_sqlalchemy import SQLAlchemy
from werkzeug import generate_password_hash, check_password_hash
from flask_login import UserMixin
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
uid = db.Column(db.Integer, primary_key = True)
firstname = db.Column(db.String(100))
lastname = db.Column(db.String(100))
email = db.Column(db.String(120), unique=True)
pwdhash = db.Column(db.String(54))
#-----login requirements-----
def is_active(self):
#all users are active
return True
def get_id(self):
# returns the user e-mail. not sure who calls this
return self.email
def is_authenticated(self):
return self.authenticated
def is_anonymous(self):
# False as we do not support annonymity
return False
def __init__(self, firstname, lastname, email, password):
self.firstname = firstname.title()
self.lastname = lastname.title()
self.email = email.lower()
self.set_password(password)
def set_password(self, password):
self.pwdhash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pwdhash, password)
You're using User.query.get(uid) where you need to use filter or filter_by:
#login_manager.user_loader
def user_loader(user_email):
"""Given *user_id*, return the associated User object.
:param unicode user_id: user_id (email) user to retrieve
"""
return User.query.filter_by(email=user_email).first()
get() takes a Primary Key (which would be user id in this case) and returns it, filter is what you need here if you're trying to limit on a column value.

Flask Login Continuously bounces back to log in

I can't figure out why I can't get passed the login page. It doesn't matter if I type in the right or wrong credentials, It reloads the login page, instead of signing me in.
import json
from flask import Flask, render_template, request, url_for, redirect
from flask.ext.bootstrap import Bootstrap
from flask.ext.login import LoginManager, UserMixin, login_required, login_user, current_user
from bson.objectid import ObjectId
from lib.mongo import db
from scripts.twitter_stats import ratio_of_wiki_links
app = Flask(__name__)
app.config["SECRET_KEY"] = ''
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
bootstrap = Bootstrap(app)
class User(UserMixin):
def __init__(self, name, password, id, active=True):
self.name = name
self.password = password
self.id = id
self.active = active
def is_active(self):
account = db.accounts.find_one({ "_id": ObjectId("561c7990e4b060b59d7cbcd1")})
if not account['username'] == self.name and account['password'] == self.password:
self.active = False
return self.active
def is_anonymous(self):
return False
def is_authenticated(self):
return True
def get_id(self):
return str(db.accounts.find_one({'username': self.name})['_id'])
#login_manager.user_loader
def load_user(userid):
user = db.accounts.find_one({'_id': userid})
return user
#app.route('/login', methods=['POST', 'GET'])
def login():
account = db.accounts.find_one({ "_id": ObjectId("561c7990e4b060b59d7cbcd1")})
password = account['password']
user = account['username']
error = None
if request.method == 'POST':
username = request.form['username']
passw = request.form['password']
if username != user or passw != password:
error = 'Invalid Credentials, please try again'
else:
user = User(username, passw, account['_id'])
login_user(user)
return redirect(url_for('home'))
return render_template('login.html', error=error)
#app.route('/')
#login_required
def home():
account = db.accounts.find_one({'account': 'twitter'})
entry = db.tweets.find().sort([['_id', -1]]).limit(1)
entry = list(entry)[0]['post']
# if g.user.is_authenticated():
# g.user = user.name
return render_template('index.html', account=account, entry=entry)
You should call add_routes before run app
if __name__ == '__main__':
add_routes(app)
app.run(debug=True)
For those of you struggling with the same issue, my problem was with the load_user method. I fixed it by changing it to this:
#login_manager.user_loader
def load_user(userid):
user_rec = db.accounts.find_one({'_id': ObjectId(userid)})
user = User(user_rec['username'], user_rec['password'], user_rec['_id'])
return user

Categories

Resources