I'm creating my first Flask project. The first part of the project is obviusly the login part. I made with html tho page for sign up and login. Then I wrote the flask part of the project. The code is the following, divided in the main.py file
from flask import Flask, render_template, redirect, url_for, session
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine
from os import path
from flask_login import LoginManager
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__,static_url_path='/static')
app.secret_key = "referendumKey"
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False
db.init_app(app)
#importation of all blueprints created
from .auth import auth
from .views import views
app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(views, url_prefix='/')
#model import
from .models import Refs, User
create_database(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
return app
#If you haven't already created a database, it will be created
def create_database(app):
if not path.exists('website/' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
Then, the authentication file (auth.py)
from flask import Blueprint, render_template, session, redirect, url_for, request, flash
from .models import User
from . import db
from flask_login import login_user, login_required, logout_user, current_user
auth = Blueprint("auth", __name__)
@auth.route("/login", methods=["GET", "POST"])
def login():
if request.method == 'POST':
name =request.form.get("username")
psw =request.form.get("psw")
user = User.query.filter_by(name=name).first()
if user:
if psw == user.password:
flash("Logged succesfully", category="success")
login_user(user, remember=True)
return redirect(url_for("views.home"))
else:
flash("Incorrect password", category="error")
else:
flash("Unexistent user", category="error")
return render_template("login.html", user=current_user)
@auth.route("/signup", methods=["GET", "POST"])
def signup():
if request.method=="POST":
username=request.form.get('username')
psw1=request.form.get('psw1')
psw2=request.form.get('psw2')
user = User.query.filter_by(name=username).first()
if user:
flash("Username already exist", category="error")
elif len(username)<3:
flash("Username too short", category="error")
elif psw1!=psw2:
flash("Passwords are different", category="error")
else:
new_user = User(name=username, password=psw1)
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash("Account created", category="Success")
return redirect(url_for(views.home))
return render_template("signup.html", user=current_user)
@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))
And, the views.py file, that should let people see the home page with content
from flask import Blueprint, render_template, request, flash, jsonify
from flask_login import login_required, current_user
from . import db
views = Blueprint('views', __name__)
@views.route("/")
@views.route("/home")
@login_required
def home():
return render_template("home.html")
To store the datatypes, I used the models in the following code
from . import db
from flask_login import UserMixin
from sqlalchemy.sql import func
"""
Definire la classe che identidica un Referendum, inserendovi:
id di colonna, la domanda, la prima e la seconda risposta
possibili, i voti che hanno ricevuto, chi ha votato già, l'id
dell'utente che possiede il ref
"""
class Refs(db.Model):
id = db.Column(db.Integer,primary_key=True)
question = db.Column(db.String(200))
fAnsw = db.Column(db.String(200))
sAnsw = db.Column(db.String(200))
fVote = db.Column(db.Integer, default=0)
sVote = db.Column(db.Integer, default=0)
voters = db.Column(db.ARRAY(db.Integer))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
"""
Definire la classe utente inserendo il suo nome, la sua
password, e tutti i Referendum da lui creato
"""
class User(db.Model,UserMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
refs = db.relationship('Refs')
Now, there is a problem. If I try to create a new account, or to login, there is an error. The error is the following one.
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user
[SQL: SELECT user.id AS user_id, user.name AS user_name, user.password AS user_password
FROM user
WHERE user.name = ?
LIMIT ? OFFSET ?]
[parameters: ('sadas', 1, 0)]
(Background on this error at: http://sqlalche.me/e/14/e3q8)
And it shows the follow part of the code:
user = User.query.filter_by(name=name).first()
I guess the problem is in the model of the database, because it shows up a SQLAlchemy error. Probably I used an incorrect syntax. I read a lot of github repository, and also the official documentation (https://docs.sqlalchemy.org/en/14/),and even the link relased by the compiler, but I can't understand, I think I wrote it correctly. The error can even be in the flask_login API usage, but reading error and documentation I guess it isn't. Can someone help me please? Thanks