500 尝试呈现配置文件页面时 flask 出现内部服务器错误

问题描述 投票:0回答:0

我正在尝试构建一个带有登录、个人资料和聊天页面的小型 Flask 应用程序。但是,当我尝试单击个人资料页面时,我一直遇到___。我无法真正找到我的问题,但就我而言,这是唯一不起作用的部分。尽管以防万一我展示了我项目中的所有其他内容。

如果我的问题是业余的,我很抱歉,但我对此非常陌生,所以请注意。

因此,我仍在使用模拟数据库,但希望切换到本地数据库。任何建议将不胜感激。

代码快速概览

代码是一个创建简单聊天室的 Flask 应用程序。用户可以登录、向聊天室发送消息以及邀请其他用户加入聊天室。该应用程序使用 Flask-Login 来处理用户身份验证和授权,并使用 Flask-SocketIO 来实现客户端和服务器之间的 WebSocket 通信。

应用程序有四种方法:

/注册: 该路由处理用户登录。使用 GET 请求呈现登录表单,并使用 POST 请求处理表单数据。如果提交的凭据有效,用户将登录并重定向到主页。否则,您将收到一条错误消息。

/注销: 此路由注销当前用户并重定向到登录页面。

/: 这是应用程序的主页。出现一个聊天室,用户可以在其中发送消息并邀请其他用户加入聊天室。

/简介: 此路由显示用户的个人资料页面,其中包括他们的姓名和电子邮件地址。只有经过身份验证的用户才能访问此页面。

应用程序使用 Flask-SocketIO 来处理客户端和服务器之间的 WebSocket 通信。当用户在聊天室中发送消息时,消息通过 WebSocket 发送到服务器,服务器将消息广播到所有连接的客户端。类似地,当用户邀请另一个用户进入聊天室时,邀请通过 WebSocket 发送到服务器,并向受邀用户发送电子邮件。

app.py

from flask import Flask, render_template, request, redirect, url_for, flash
from flask_login import LoginManager, login_user, logout_user, login_required, UserMixin
from flask_bcrypt import Bcrypt

app = Flask(__name__)
app.secret_key = 'kO=:6KafW}GT~~l[rle/;yAyE_nAQ^'  # change this to a more secure secret key
bcrypt = Bcrypt(app)

# configure Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

# create a mock user database
users = {'user1': {'password': bcrypt.generate_password_hash('password').decode('utf-8'),
                   'name': 'John Doe',
                   'email': '[email protected]'},
         'user2': {'password': bcrypt.generate_password_hash('password2').decode('utf-8'),
                   'name': 'Jane Smith',
                   'email': '[email protected]'}}

# create a User class for Flask-Login
class User(UserMixin):
    def __init__(self, id):
        self.id = id

    def __repr__(self):
        return self.id

# define a function to load users from the database
@login_manager.user_loader
def load_user(user_id):
    if user_id in users:
        return User(user_id)
    return None

# define the login route
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        # check if the submitted credentials are valid
        if request.form['username'] in users and bcrypt.check_password_hash(users[request.form['username']]['password'], request.form['password']):
            user = User(request.form['username'])
            login_user(user)
            flash('Logged in successfully.')
            return redirect(url_for('index'))
        else:
            flash('Invalid username or password.')
    return render_template('login.html')

# define the logout route
@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('Logged out successfully.')
    return redirect(url_for('login'))

# define the index route
@app.route('/')
@login_required
def index():
    return render_template('index.html')

# define the profile route
@app.route('/profile')
@login_required
def profile():
    user = users.get(current_user.id)
    return render_template('profile.html', user=user)

if __name__ == '__main__':
    app.run(debug=True)

模板/base.html

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="{{ url_for('index') }}">Home</a></li>
                {% if current_user.is_authenticated %}
                    <li><a href="{{ url_for('logout') }}">Logout</a></li>
                    <li><a href="{{ url_for('profile') }}">Profile</a></li>
                {% else %}
                    <li><a href="{{ url_for('login') }}">Login</a></li>
                {% endif %}
            </ul>
        </nav>
    </header>
    <main>
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                <ul class="flashes">
                {% for message in messages %}
                    <li>{{ message }}</li>
                {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </main>
    <footer>
        <p>&copy; 2023 My Flask App</p>
    </footer>
</body>
</html>

模板/index.html

{% extends "base.html" %}

{% block title %}Chat Room{% endblock %}

{% block content %}
    <h1>Chat Room</h1>
    <div id="messages"></div>
    <form id="message-form">
        <input type="text" id="message-input" placeholder="Type your message...">
        <button type="submit">Send</button>
    </form>
    <h2>Invite People</h2>
    <form id="invite-form">
        <input type="text" id="invite-input" placeholder="Enter email address...">
        <button type="submit">Invite</button>
    </form>
{% endblock %}

{% block scripts %}
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        // connect to the WebSocket server
        const socket = new WebSocket("ws://" + location.host + "/ws");

        // when the WebSocket connection is opened, register the user
        socket.addEventListener("open", function (event) {
            socket.send(JSON.stringify({
                "type": "register",
                "data": "{{ current_user.id }}"
            }));
        });

        // when the WebSocket receives a message, add it to the chat log
        socket.addEventListener("message", function (event) {
            const message = JSON.parse(event.data);
            if (message.type === "message") {
                $("#messages").append(`<p><strong>${message.sender}: </strong>${message.text}</p>`);
            }
        });

        // when the message form is submitted, send the message over the WebSocket
        $("#message-form").submit(function (event) {
            event.preventDefault();
            const messageInput = $("#message-input");
            const messageText = messageInput.val();
            socket.send(JSON.stringify({
                "type": "message",
                "data": {
                    "sender": "{{ current_user.id }}",
                    "text": messageText
                }
            }));
            messageInput.val("");
        });

        // when the invite form is submitted, send an email invitation
        $("#invite-form").submit(function (event) {
            event.preventDefault();
            const inviteInput = $("#invite-input");
            const emailAddress = inviteInput.val();
            // TODO: send email invitation using an email API
            alert(`Invitation sent to ${emailAddress}`);
            inviteInput.val("");
        });
    </script>
{% endblock %}

templates/login.html

{% extends "base.html" %}

{% block content %}
<div class="wrap">
    <div class="avatar">
        <img src="https://static.vecteezy.com/system/resources/previews/007/636/859/original/community-logo-design-free-vector.jpg">
    </div>
    <form method="POST" action="{{ url_for('login') }}">
        <input type="text" name="username" placeholder="username" required>
        <div class="bar">
            <i></i>
        </div>
        <input type="password" name="password" placeholder="password" required>
        <button type="submit">Sign in</button>
        {{ get_flashed_messages() }}
    </form>
</div>

{% endblock %}

templates/profile.html

{% extends 'base.html' %}

{% block title %}Profile{% endblock %}

{% block content %}
  <div class="profile-container">
    <div class="profile-header">
      <img src="{{ url_for('static', filename='img/profile-pic.jpg') }}" alt="Profile Picture" class="profile-picture">
      <h1>{{ current_user.username }}</h1>
    </div>
    <div class="profile-info">
      <h2>Profile Information</h2>
      <ul>
        <li><strong>Name:</strong> {{ current_user.name }}</li>
        <li><strong>Email:</strong> {{ current_user.email }}</li>
        <li><strong>Location:</strong> {{ current_user.location }}</li>
      </ul>
    </div>
  </div>
{% endblock %}

{% block scripts %}
  <script src="{{ url_for('static', filename='js/profile.js') }}"></script>
{% endblock %}

static/css/styles.css

@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  src: local('Lato Regular'), local('Lato-Regular'), url(http://themes.googleusercontent.com/static/fonts/lato/v7/qIIYRU-oROkIk8vfvxw6QvesZW2xOQ-xsNqO47m55DA.woff) format('woff');
}

body {
    background: #448ed3 ;
    font-family: "Lato" ;
}
.wrap {
    width:250px;
    height: auto;
    margin: auto;
    margin-top: 10%;
}
.avatar {
    width: 100%;
    margin: auto;
    width: 65px;
    border-radius: 100px;
    height: 65px;
    background: #448ed3 ;
    position: relative;
    bottom: -15px;
}
.avatar img {
    width: 55px;
    height: 55px;
    border-radius: 100px;
    margin: auto;
    border:3px solid #fff;
    display: block;
}
.wrap input {
    border: none;
    background: #fff;
  font-family:Lato ;
  font-weight:700 ;
    display: block;
    height: 40px;
    outline: none;
    width: calc(100% - 24px) ;
    margin: auto;
    padding: 6px 12px 6px 12px;
}
.bar {
    width: 100%;
    height: 1px;
    background: #fff ;
}
.bar i {
    width: 95%;
    margin: auto;
    height: 1px ;
    display: block;
    background: #d1d1d1;
}
.wrap input[type="text"] {
    border-radius: 7px 7px 0px 0px ;
}
.wrap input[type="password"] {
    border-radius: 0px 0px 7px 7px ;
}
.forgot_link {
    color: #83afdf ;
    color: #83afdf;
    text-decoration: none;
    font-size: 11px;
    position: relative;
    left: 193px;
    top: -36px;
}
.wrap button {
    width: 100%;
    border-radius: 7px;
    background: #b6ee65;
    text-decoration: center;
    border: none;
    color: #51771a;
  margin-top:-5px;
    padding-top: 14px;
    padding-bottom: 14px;
    outline: none;
    font-size: 13px;
    border-bottom: 3px solid #307d63;
    cursor: pointer;
}

.profile-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 30px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.profile-header {
  display: flex;
  align-items: center;
}

.profile-picture {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  margin-right: 30px;
}

.profile-info h2 {
  margin-bottom: 20px;
}

.profile-info ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.profile-info li {
  margin-bottom: 10px;
}

.profile-info li strong {
  display: inline-block;
  width: 100px;
  font-weight: bold;
  margin-right: 10px;
}

static/js/profile.js

document.addEventListener("DOMContentLoaded", function(event) {
    // Code to run when the page loads
    console.log("Profile page loaded.");
});
html css python-3.x flask http-status-code-500
© www.soinside.com 2019 - 2024. All rights reserved.