我有一个Flask应用程序,它使用API,并有一个使用PSQL的多个表的模式。用户应该能够通过搜索栏浏览,以及点击一个流派,以检索图书结果并显示在Bootstrap卡上。用户应该能够收藏/保存一本书,然后被带到他们的个人资料页面,如果注册和登录。我似乎是成功注册,登录,有一个GET到/users/profile,但是我得到了一个ROLLBACK,我被送回登录页面。
这是我的app.py的一部分。我相信我已经导入了所有必要的依赖项。
from flask import Flask, render_template, redirect, flash, session, request, jsonify, url_for
from models import connect_db, db, User, Books
from forms import LoginForm, RegisterForm
from flask_bcrypt import Bcrypt
from flask_login import LoginManager, login_required
app = Flask(__name__, template_folder="templates", static_folder="static")
app.app_context().push()
from flask_login import current_user
from flask_login import login_user, logout_user
bcrypt = Bcrypt()
login_manager = LoginManager()
login_manager.init_app(app)
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql:///my_books"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SQLALCHEMY_ECHO"] = True
app.config["SECRET_KEY"] = ""
app.config['TESTING'] = True
import requests
API_KEY = ""
migrate = Migrate(app, db)
connect_db(app)
@app.route("/")
def home_page():
""""""
return render_template("index.html")
字符串
这是login_manager.user_loader,我相信我正确导入了user_id。
@login_manager.user_loader
def user_loader(user_id):
if user_id.isdigit():
user = User.query.get(int(user_id))
return user
return None**
型
这是我的登录GET路由,显示了登录表单。
@app.route("/users/login", methods=["GET"])
def login_form():
"""Displays the login form."""
form = LoginForm()
return render_template('users/login.html', form=form)
型
这是我的登录路线,应该带我到profile.html页面一旦登录。
from flask import current_app
@app.route("/users/login", methods=["POST"])
def login():
"""Displays login form. Logs in the current user by processing the form"""
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
print("Username from form:", form.username.data)
print("User from the database:", user)
if user:
if login_user(user):
print("Login successful")
flash(f"Hello, {user.username}!", "success")
db.session.commit() # Commit the transaction to the database
return redirect(url_for('profile'))
else:
print("Login failed")
flash("Failed to log in the user.", "danger")
else:
print("User not found")
flash("User not found.", 'danger')
else:
flash("Invalid credentials.", 'danger')
return render_template('users/login.html', form=form)
型
我做了许多flash和print语句,我想是因为回滚的原因,这些语句没有出现。
@app.route("/users/logout", methods=["GET"])
def logout():
"""Logout the current user."""
logout_user() # Use Flask-Login logout_user function
return redirect(url_for('home_page'))
@app.route('/users/register', methods=["GET", "POST"])
def handle_registration():
"""Creates a new user and adds user to the DB. Makes sure username & email are unique."""
form = RegisterForm()
if form.validate_on_submit():
# Check if a user with the same username or email already exists
existing_user = User.query.filter((User.username == form.username.data) | (User.email == form.email.data)).first()
if existing_user:
flash("Username or email already taken", 'danger')
return render_template('users/register.html', form=form)
user = User.signup(
first_name=form.first_name.data,
last_name=form.last_name.data,
username=form.username.data,
password=form.password.data,
email=form.email.data,
)
db.session.commit()
flash("Registration successful! Please log in.", 'success')
return redirect(url_for('login_form'))
return render_template('users/register.html', form=form)
from flask_login import current_user
@app.route('/users/profile', methods=["GET"])
def profile():
if current_user.is_anonymous:
flash("You need to log in to see your profile.", 'warning')
return redirect(url_for('login'))
print("Profile route accessed")
# Retrieve the current user's favorite books
favorite_books = current_user.saved_books
return render_template('users/profile.html', favorite_books=favorite_books)
型
我的Flask应用程序加载,我可以浏览,搜索和注册假帐户,所以WTForms的注册页面可以正常工作。当我进入登录页面并输入我的用户名和密码时,我可以看到HTML中的登录标记已经切换到注销标记,所以这似乎也可以正常工作。我还检查了我的模式中的所有数据库都显示在PSQL中。
这是我的models.py:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from flask_login import UserMixin
db = SQLAlchemy()
saved_books_association = db.Table(
'saved_books_association',
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('book_id', db.Integer, db.ForeignKey('books.id'))
)
型
这是User类继续models.py。我试图跟随沿着与真实的Python网站。
class User(db.Model, UserMixin):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False, unique=True)
first_name = db.Column(db.String(20), nullable=False)
last_name = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(50), nullable=False)
password = db.Column(db.String(100), nullable=False)
saved_books = db.relationship('Books', secondary=saved_books_association, backref=db.backref('users', lazy='dynamic'))
def __init__(self, first_name, last_name, username, email, password):
self.first_name = first_name
self.last_name = last_name
self.username = username
self.email = email
self.password = bcrypt.generate_password_hash(password).decode('utf-8')
def check_password(self, password):
return bcrypt.check_password_hash(self.password, password)
@classmethod
def signup(cls, first_name, last_name, username, password, email):
"""Sign up a new user and return the user object."""
user = cls(first_name=first_name, last_name=last_name, username=username, password=password, email=email)
db.session.add(user)
return user
def is_active(self):
"""True, as all users are active."""
return True
def get_id(self):
"""Return the user's ID as a string to satisfy Flask-Login's requirements."""
return str(self.id)
def is_anonymous(self):
"""Return True if the user is anonymous, or False if authenticated."""
return not self.is_authenticated()**
型
我还有其他没有包含的DB模型。这是运行Flask应用程序时终端中的消息:
127.0.0.1 - - [01/Nov/2023 19:30:09] "POST /users/login HTTP/1.1" 302 -
2023-11-01 19:30:09,361 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-11-01 19:30:09,361 INFO sqlalchemy.engine.Engine SELECT users.id AS users_id, users.username AS users_username, users.first_name AS users_first_name, users.last_name AS users_last_name, users.email AS users_email, users.password AS users_password
FROM users
WHERE users.id = %(pk_1)s
2023-11-01 19:30:09,361 INFO sqlalchemy.engine.Engine [cached since 23.39s ago] {'pk_1': 1}
2023-11-01 19:30:09,362 INFO sqlalchemy.engine.Engine ROLLBACK
127.0.0.1 - - [01/Nov/2023 19:30:09] "GET /users/profile HTTP/1.1" 302 -
2023-11-01 19:30:09,367 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-11-01 19:30:09,367 INFO sqlalchemy.engine.Engine SELECT users.id AS users_id, users.username AS users_username, users.first_name AS users_first_name, users.last_name AS users_last_name, users.email AS users_email, users.password AS users_password
FROM users
WHERE users.id = %(pk_1)s
2023-11-01 19:30:09,367 INFO sqlalchemy.engine.Engine [cached since 23.4s ago] {'pk_1': 1}
2023-11-01 19:30:09,369 INFO sqlalchemy.engine.Engine ROLLBACK
127.0.0.1 - - [01/Nov/2023 19:30:09] "GET /users/login HTTP/1.1" 200 -
型
我已经尝试删除我的数据库并重新创建它,更改为使用UserMixin,并重新修改了我的User类模型无数次,我仍然停留在回滚上。任何建议都将是一个很大的帮助。
1条答案
按热度按时间qnakjoqk1#
每次使用会话时,都会自动启动一个事务,然后它将被回滚。所以这可能是不相关的。
if current_user.is_anonymous:
应该是像if current_user.is_anonymous():
这样的函数调用吗?