我正在使用烧瓶(app.py)运行 home.html、reister.html、login.html 和仪表板.html 文件,并在一次又一次重定向到登录页面时遇到错误。 我已经使用了数据库方法,并且 Flask 也在执行,但是在注册并登录(而不是仪表板)后运行时,它再次移动到登录页面,并且在登录页面中输入数据时没有错误
这是烧瓶代码
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
def __repr__(self):
return f'<User {self.username}>'
@app.route('/')
def home():
return render_template('home.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
if not request.form.get('username'):
flash('Username is required!')
return redirect(url_for('register'))
if not request.form.get('password'):
flash('Password is required!')
return redirect(url_for('register'))
username = request.form['username']
password = request.form['password']
if User.query.filter_by(username=username).first():
flash('Username already exists!')
return redirect(url_for('register'))
user = User(username=username, password=generate_password_hash(password))
db.session.add(user)
db.session.commit()
flash('Registration successful!')
return redirect(url_for('login'))
return render_template('register.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
if 'username' not in request.form or 'password' not in request.form:
flash('Username and password are required!')
return redirect(url_for('login'))
username = request.form['username']
password = request.form['password']
user = User.query.filter_by(username=username).first()
if not user or not check_password_hash(user.password, password):
flash('Invalid username or password!')
return redirect(url_for('login'))
login_user(user)
flash('Login successful!')
next_page = request.args.get('next')
return redirect(next_page or url_for('dashboard'))
return render_template('login.html')
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('Logout successful!')
return redirect(url_for('home'))
@app.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html', user=current_user)
if __name__ == '__main__':
with app.app_context():
db.create_all()
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
app.run(debug=True)
这是 html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-image: url('https://source.unsplash.com/random');
background-size: cover;
background-position: center;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
.nav {
display: flex;
justify-content: space-around;
background-color: rgba(0, 0, 0, 0.5);
padding: 10px;
animation: fadeIn 2s;
}
.nav a {
color: #fff;
text-decoration: none;
}
.nav a:hover {
color: #ccc;
}
.hero {
background-color: rgba(0, 0, 0, 0.5);
padding: 50px;
text-align: center;
animation: fadeIn 2s;
}
.footer {
background-color: rgba(0, 0, 0, 0.5);
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Welcome to the Home Page</h1>
</div>
<div class="nav">
<a href="{{ url_for('register') }}">Register</a>
<a href="{{ url_for('login') }}">Login</a>
</div>
<div class="hero">
<h2>Welcome to Our Website</h2>
</div>
<div class="footer">
<p>© 2022 All Rights Reserved</p>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-image: url('https://source.unsplash.com/random');
background-size: cover;
background-position: center;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
animation: fadeIn 2s;
}
.header {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
animation: fadeIn 2s;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 3px;
animation: fadeIn 2s;
}
.form-group input:focus {
border-color: #6699cc;
outline: none;
animation: fadeIn 2s;
}
.form-group button {
background-color: #333;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
animation: fadeIn 2s;
}
.form-group button:hover {
background-color: #555;
animation: fadeIn 2s;
}
.footer {
background-color: rgba(0, 0, 0, 0.5);
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Register</h1>
</div>
<form action="{{ url_for('register') }}" method="post">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email">Email address:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="confirm-password">Confirm Password:</label>
<input type="password" id="confirm-password" name="confirm-password" required>
</div>
<div class="form-group">
<input type="checkbox" id="terms" name="terms" required>
<label for="terms">I accept the terms and conditions.</label>
</div>
<div class="form-group">
<button type="submit">Register</button>
</div>
</form>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-image: url('https://source.unsplash.com/random');
background-size: cover;
background-position: center;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
animation: fadeIn 2s;
}
.header {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
animation: fadeIn 2s;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 3px;
animation: fadeIn 2s;
}
.form-group input:focus {
border-color: #6699cc;
outline: none;
animation: fadeIn 2s;
}
.form-group button {
background-color: #333;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
animation: fadeIn 2s;
}
.form-group button:hover {
background-color: #555;
animation: fadeIn 2s;
}
.footer {
background-color: rgba(0, 0, 0, 0.5);
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Login</h1>
</div>
<form action="{{ url_for('login') }}" method="post">
<div class="form-group">
<label for="username_or_email">Username or Email Address:</label>
<input type="text" id="username_or_email" name="username_or_email" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<button type="submit">Login</button>
</div>
</form>
</div>
<div class="footer">
<p>© 2022 All Rights Reserved</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-image: url('https://source.unsplash.com/random');
background-size: cover;
background-position: center;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
animation: fadeIn 2s;
}
.header {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
.user-info {
margin-bottom: 20px;
animation: fadeIn 2s;
}
.user-info p {
margin-bottom: 10px;
}
.form-group {
animation: fadeIn 2s;
}
.form-group button {
background-color: #333;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
animation: fadeIn 2s;
}
.form-group button:hover {
background-color: #555;
animation: fadeIn 2s;
}
.footer {
background-color: rgba(0, 0, 0, 0.5);
padding: 20px;
text-align: center;
animation: fadeIn 2s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Dashboard</h1>
</div>
<div class="user-info">
<p>Welcome, {{ user.username }}!</p>
<p>Your email address is {{ user.email }}</p>
</div>
<form action="{{ url_for('logout') }}" method="post">
<div class="form-group">
<button type="submit">Logout</button>
</div>
</form>
</div>
<div class="footer">
<p>© 2022 All Rights Reserved</p>
</div>
</body>
</html>
在
login.html
页面中,用户名的输入字段名为 username_or_email
。但是,在端点内,会查询表单是否有 username
。因此,用户名未知,登录过程失败。
将输入字段的名称属性设置为
username
,您的应用程序将按预期运行。
<input type="text" id="username_or_email" name="username" required>