Флэш-сообщение колбы не отображается при нажатии кнопки

#python #jquery #flask #flask-sqlalchemy #flask-login

Вопрос:

Я создал веб-приложение с использованием начальной загрузки для интерфейса в flask (python). Мое приложение состоит из кнопки входа, чтобы запустить режим входа, чтобы мы могли ввести учетные данные.

Я также написал java-скрипт, который проверяет, вошел ли пользователь в систему перед запуском модального входа. Если пользователь вошел в систему, он перенаправляется в функцию (функция check_login в маршрутах.py), который состоит из флэш-сообщения о том, что «пользователь уже вошел в систему!». Однако проблема, с которой я сталкиваюсь, заключается в том, что флэш-сообщение не отображается, если кнопка входа нажата при входе пользователя. Пожалуйста, объясните причину этого и предложите способ исправить это.

base.html (другие html — страницы расширяются/наследуются от этой страницы)

 <!DOCTYPE html>
<html lang="english">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="shortcut icon" href={{url_for("static", filename="images/logo1.png")}}>

    <title>{% block title%}{% endblock %}</title>

    <!-- Bootstrap CSS CDN -->    
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii scO/bJGFsiCZc 5NDVN2yr8 0RDqr0Ql0h rP48ckxlpbzKgwra6" crossorigin="anonymous">

    <!-- Bootstrap icons css -->
    <link rel="stylesheet" href={{url_for("static", filename="bootstrap-icons/bootstrap-icons.css")}}>

    <!-- Font Awesome JS (icons) -->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S oqd12jhcu A56Ebc1zFSJ" crossorigin="anonymous">
    <script defer src="https://use.fontawesome.com/releases/v5.0.13/js/solid.js" integrity="sha384-tzzSw1/Vo 0N5UhStP3bvwWPq uvzCMfrN1fEFe xBmv1C/AtVX5K0uZtmcHitFZ" crossorigin="anonymous"></script>
    <script defer src="https://use.fontawesome.com/releases/v5.0.13/js/fontawesome.js" integrity="sha384-6OIrr52G08NpOFSZdxxz1xdNSndlD4vdcf/q2myIUVO0VsqaGHJsB0RaBE01VTOY" crossorigin="anonymous"></script>



    <!-- Our Custom CSS -->
    <link rel="stylesheet" href={{url_for("static", filename="stylesheets/style.css")}}>

</head>

<body>

    <!--............................Message flashing................................-->
    {% with messages = get_flashed_messages(with_categories=true) %} 
        {% if messages %} 
            {% for category, message in messages %} 
                {% if category == "error" %}
                    <div class="alert alert-danger alter-dismissable fade show" role="alert">
                        {{ message }}
                        <button type="button" class="close" data-dismiss="alert">
                        <span aria-hidden="true">amp;times;</span>
                        </button>
                    </div>
                {% else %}
                    <div class="alert alert-success alter-dismissable fade show" role="alert">
                        {{ message }}
                        <button type="button" class="close" data-dismiss="alert">
                        <span aria-hidden="true">amp;times;</span>
                        </button>
                    </div>
                {% endif %} 
            {% endfor %} 
        {% endif %} 
    {% endwith %}

    <!--............................Home page navbar................................-->
    <div class="container-fluid">
        <nav class=" navbar navbar-expand-lg navbar-light fixed-top bg-light py-lg-0 " id="customNavbar">  
            <a class="navbar-brand" href="/">
                <!-- Add logo -->
                <img src={{url_for("static", filename="images/logo1.png")}} alt="logo">
            </a>
            
            <button class="navbar-toggle-collapsed d-block d-sm-block d-md-none" type="button"
                    data-toggle="collapse" 
                    data-target="#navbarResponsive"
                    aria-controls="navbarResponsive" 
                    aria-expanded="true" 
                    aria-label="Toggle navigation"
                    id="togglerButton">
                    
                    <span class="line"></span> 
                    <span class="line"></span> 
                    <span class="line" style="margin-bottom: 0;"></span>
            </button>
    
            <div class="collapse navbar-collapse" id="navbarResponsive">
                <ul class="navbar-nav ml-auto">
                    <li class="nav-item active">                        
                        <a class="nav-link" href="/"><i class="fas fa-home"></i> Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/Services"><i class="fas fa-cog"></i> Services</a>                        
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/Otherpage"><i class="fas fa-cog"></i> Other</a>                        
                    </li>


            <!-- Credentials (Signin, logout, signup) -->

                <button type="button" name="signin-btn" class="btn buttonCustom" id="signin-btn" data-bs-toggle="modal">Sign In</button>


                <a class="btn buttonCustom" href="/Logout"> Logout</a>                                   
                <button type="button" name="signup-btn" class="btn buttonCustom" id="signup-btn" data-bs-toggle="modal" data-bs-target="#signupModal">Sign Up</button>
            </form>
        </nav>    
    </div>

<!--...............Tab contents (Home, services).......................--> 
    {% block navPages%}{% endblock%}

    <!--.................................Signin modal................................-->
 

        <div class="modal fade" id="signinModal" data-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
            <form method="POST">
            <div class="modal-dialog modal-dialog-scrollable modal-lg">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3 class="modal-title col-11 text-center">Login</h3>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">                   

                        <div class="input-group mb-3">
                            <span class="input-group-text"><i class="bi bi-envelope-fill"></i></span>
                            <input type="email" class="form-control clearAfterClose" name="email" placeholder="Email adress">
                        </div>

                        <div class="input-group mb-3">
                            <span class="input-group-text"><i class="bi bi-lock-fill"></i></span>
                            <input id="password" type="password" class="form-control clearAfterClose" name="password" placeholder="Password">
                        </div>

                        <div class="custom-control custom-checkbox mb-3"> <input type="checkbox" class="custom-control-input" id="customCheck1"> <label class="custom-control-label" for="customCheck1">Remember password?</label> </div>
                        
                        <div class="etc-login-form" >
                            <p>forgot your password? <a id="ref_link" href="#">click here</a></p>
                            <p>new user? <a id="ref_link" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#signupModal">create new account</a></p>
                        </div>                          
                        
                        <hr class="my-4"> 
                        <div class="row justify-content-center">
                            <div class="col-4">
                                <a class="btn btn-google" type="submit"><i class="bi bi-google"></i> Sign in with Google</a>
                            </div>
                            <div class="col-4">
                                <a class="btn btn-facebook" type="submit"><i class="bi bi-facebook" id="facebook2"></i> Sign in with Facebook</a>
                            </div>
                        </div>                  

                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                        <button type="submit" class="btn buttonCustom2">Sign in</button>
                    </div>
                </div>
            </div>
            </form>
        </div>


    <!--.................................Signup modal................................-->

    <form method="POST">
    <div class="modal fade" id="signupModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
        <div class="modal-dialog modal-dialog-scrollable modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <div class="row">
                        <div class="col-1"></div>
                        <h3 class=" col-10 modal-title  text-center">Sign Up</h3>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>                    
                    </div>
                    <br/>
                    <div class="row">
                        <div class=" col-12 etc-login-form text-center">
                            <p>Already a user? <a id="ref_link" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#signinModal">Login</a></p>
                        </div>                     
                    </div>                  
                </div>
                
                <div class="modal-body">                 
                    <div class="input-group mb-3">
                        <span class="input-group-text" id="name"><i class="bi bi-person-fill"></i></span>
                        <input type="text" aria-label="signupFirstName" name="firstName" class="form-control clearAfterClose" placeholder="First name">
                        <input type="text" aria-label="lastName" name="lastName" class="form-control clearAfterClose" placeholder="Last name">
                    </div>
                    <div class="input-group mb-3">
                        <span class="input-group-text"><i class="bi bi-envelope-fill"></i></span>
                        <input type="email" class="form-control clearAfterClose" name="email" placeholder="Email adress">
                    </div>

                    <div class="input-group mb-3">
                        <span class="input-group-text"><i class="bi bi-lock-fill"></i></span>
                        <input id="password" type="password" class="form-control clearAfterClose" name="password1" placeholder="Password">
                        <input id="confirmPassword" type="password" class="form-control clearAfterClose" name="confirmPassword" placeholder="Confirm password">
                    </div>

                    <div class="custom-control custom-checkbox mb-3"> <input type="checkbox" class="custom-control-input" id="customCheck1"> <label class="custom-control-label" for="customCheck1">Remember password?</label> </div>
                    
                    <div class="form-group login-group-checkbox">
                        <input type="radio" class="" name="male" id="male" placeholder="username">
                        <label for="male">male</label>
                        
                        <input type="radio" class="" name="female" id="female" placeholder="username">
                        <label for="female">female</label>
                    </div>

                    <hr class="my-4"> 
                    <div class="form-group login-group-checkbox">
                        <input type="checkbox" class="" id="reg_agree" name="reg_agree">
                        <label for="reg_agree">I agree with <a id="ref_link" href="#">Terms and conditions</a></label>
                    </div>

                    <hr class="my-4">
                    <div class="row justify-content-center">
                        <div class="col-4">
                            <button class="btn btn-google" type="submit"><i class="bi bi-google"></i> Sign up with Google</button>
                        </div>
                        <div class="col-4">
                            <a href="https://www.google.com/" id="fb_signup" class="btn btn-facebook" type="submit"><i class="bi bi-facebook" id="facebook2"></i> Sign up with Facebook</a>
                        </div>
                    </div>
                </div>    
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                    <button type="submit" class="btn buttonCustom2">Register</button>
                </div>                
            </div>
        </div>
    </div>
    </form>

    <!-- javascript to enable bootstrap usage -->    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js" integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ=" crossorigin="anonymous"></script> 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho j7jyWK8fNQe A12Hb8AhRq26LrZ/JpcUGGOn Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy 8" crossorigin="anonymous"></script>

    <!-- javascript to clear signin modal fields after close -->
    <script>
        $("#signinModal").on("hidden.bs.modal", function(e) {
            $(".clearAfterClose").val("");
        });
    </script>

    <!-- javascript to clear signup modal fields after close -->
    <script>
        $("#signupModal").on("hidden.bs.modal", function(e) {
            $(".clearAfterClose").val("");
        });
    </script>

   <!-- javascript to check if user is logged in -->
   {% if current_user.is_anonymous %}
        <script>
            var myElement = document.querySelector('#signin-btn');
            myElement.addEventListener("click", function(e){
                e.preventDefault();
                $("#signinModal").modal('show');                   
            });
        </script>
    {% else %}        
        <script>                
            var myElement = document.querySelector('#signin-btn');
            myElement.addEventListener("click", function(e){
                e.preventDefault();
                $.get('/check_login');                   
            });
        </script>
    {% endif %}

</body>

</html>
 

Home.html

 {% extends 'base.html'%}

{% block title %}Home{% endblock %}

{% block navPages%}
    <h1> Home Page! </h1>
    <p>
        {{file|safe}}
    </p>
{% endblock%}
 

Services.html

 {% extends 'base.html'%}
{% block title %}Our Services{% endblock %}

{% block navPages%}
    <h1> Service page! </h1>

{% endblock%}
 

otherpage.html

 {% extends 'base.html'%}

{% block title %}Other{% endblock %}

{% block navPages%}
    <h1> Other Page! </h1>
{% endblock%}
 

init.py (double underscores before and after init not visible)

 from flask import Flask
from .routes import routes
from .extensions import db
from os import path
from flask_login import LoginManager
from .dbmodels import Subscriber_va

DB_NAME = "mysubscribers_va.db"

def create_app():
    app = Flask(__name__)    
        
    #..........................Register blueprint.......................#
    app.register_blueprint(routes, url_prefix='/') 
    
    #..........................Database config.......................#
    app.config['SECRET_KEY'] = 'hello guys'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'     
    db.init_app(app)  
    create_database(app)
    
    #..........................Login manager.......................#
    login_manager = LoginManager()
    login_manager.login_view = 'routes.home'
    login_manager.login_message = 'Please login to access this page!'
    login_manager.login_message_category = 'error'    
    login_manager.init_app(app)
    
    @login_manager.user_loader
    def load_user(id):
        return Subscriber_va.query.get(int(id))    
      
    return app

def create_database(app):
    if not path.exists('Website/'   DB_NAME):
        db.create_all(app=app)
        print(DB_NAME ' database created Successfully!')
 

dbmodels.py

 from .extensions import db
from datetime import datetime
from flask_login import UserMixin

class Subscriber_va(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    firstName = db.Column(db.String(50), nullable=False)
    lastName = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(50), nullable=False, unique=True)
    password = db.Column(db.String(50), nullable=False)
    date_created = db.Column(db.String(20), default=datetime.now().strftime("%d-%m-%Y %H:%M"))
 

extensions.py

 from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
 

routes.py

 from flask import render_template, Blueprint, request, redirect, url_for, flash
from .extensions import db
from .dbmodels import Subscriber_va
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import login_required, login_user, current_user, logout_user
import pandas as pd

routes = Blueprint('routes', __name__)

btnDict = {}

f_home = open('Website/static/data/Home.txt', 'r', encoding="utf8")
file_home = f_home.read()

@routes.route('/', methods=['GET', 'POST'])
def home():
    button_clicked()
    return render_template('Home.html',  file=file_home.replace('n', '<br>'))

@routes.route('/Services', methods=['GET', 'POST'])
@login_required
def Services():          
    return render_template('Services.html')

@routes.route('/Otherpage', methods=['GET', 'POST'])
def other():          
    return render_template('otherpage.html')

@routes.route('/Logout', methods=['GET', 'POST'])
def logout():
    if current_user.is_active:
        logout_user()
        flash('Logged out successfully!', category='success')
        return redirect(url_for('routes.home'))
    else:
        flash('Please login to your account!', category='error')
        return redirect(url_for('routes.home'))
    
    
@routes.route('/check_login')
def check_login():
    flash('User already logged in!', category='error')
    return "nothing"


#...........................Subscriber database methods...........................#
def button_clicked():
    if request.method == 'POST':
        
        btnDict = dict(request.form)
        print(btnDict) 
        if len(btnDict) > 2:
            add_subscriber()
        else:
            print(len(btnDict))
            authorize()

def authorize():
    if request.method == 'POST':
        email = request.form.get('email')
        password = request.form.get('password')
        subscriber = Subscriber_va.query.filter_by(email=email).first()    
        if subscriber:
            if check_password_hash(subscriber.password, password):
                flash('Logged in successfully!', category='success')
                login_user(subscriber, remember='True')
            else:
                flash('Incorrect password, try again.', category='error') 
        else:
            flash('Email does not exist! Sign up to create an account', category='error')

def add_subscriber():
    if request.method == 'POST':
        firstName = request.form.get('firstName')
        lastName = request.form.get('lastName')
        email = request.form.get('email')
        password1 = request.form.get('password1')
        confirmPassword = request.form.get('confirmPassword')
        subscriber = Subscriber_va.query.filter_by(email=email).first()
        if subscriber:
            flash('Email already exist! Please enter different mail ID ', category='error')
        elif password1 != confirmPassword:    
                flash('Password and Confirm password donot match', category='error')
        else:      
            new_subscriber = Subscriber_va(firstName=firstName, lastName=lastName, email=email, password=generate_password_hash(password1, 'sha256'))
            db.session.add(new_subscriber)
            db.session.commit() 
            flash('Account created successfully!', category='success')
 

main.py

 from Website import create_app

app = create_app()

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

Комментарии:

1. флэш — сообщение отображается, но только когда я перехожу на другую страницу, но не на той же странице, когда я нажимаю кнопку.

Ответ №1:

Это может быть решением проблемы.
Сделать а

 return redirect(url_for('index'))
 

если вам нравится флэш-сообщение на странице индекса после действия

Смотрите в документах:
https://flask.palletsprojects.com/en/2.0.x/patterns/flashing/

Вы не приводите пример того, как вы включаете сообщения flask в свой шаблон.