Skip to content
enoch2022new edited this page Mar 28, 2024 · 15 revisions

Flask Sqlalchemy

The model will generate a table name by converting the CamelCase class name to snake_case.

Usage

create db:

def init_db():
    with app.app_context():
        db.init_app(app)
        db.drop_all()
        db.create_all()

in service.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# query one
user = db.get_or_404(User, id)

# query list
users = db.session.execute(db.select(User).order_by(User.username)).scalars()

# insert
user = User(
            username=request.form["username"],
            email=request.form["email"],
        )
db.session.add(user)
db.session.commit()

# delete
user = db.get_or_404(User, id)
db.session.delete(user)
db.session.commit()

# update
# To update data, modify attributes on the model objects
user.verified = True
db.session.commit()

Flask Blueprint

In Flask, you can organize your applications using Blueprints, a built-in concept in Flask similar to Python modules. The purpose of using blueprint is to organize your application based on modules, which meets the Single Responsibility Principle.

There are serveral steps when you want to register a module into your Flask app.

  1. create a folder under /app, like: /app/auth.
  2. create a __init__.py under /app/auth, make it a python module.
  3. In the __init__.py, register the blueprint routes.
from flask import Blueprint

auth_bp = Blueprint(
    "auth", __name__, template_folder="templates", static_folder="static"
)

from . import routes
  1. In your routes.py, use blueprint anoatation to create endpoints.
from app.auth import auth_bp

@auth_bp.route("/logout")
def logout():
    """Log out the user."""
    logout_user()
    flash("You have been logged out.")
    return redirect(url_for("index"))
  1. In your create_app() function, register blueprint.
from app.auth import auth_bp

app.register_blueprint(auth_bp)
  1. Every blueprint can have its own template and static folder.

A typical Flask blueprint app looks like this:

image

Flask Login

Overall

Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods of time.

It will:

Store the active user’s ID in the Flask Session, and let you easily log them in and out.

Let you restrict views to logged-in (or logged-out) users. (login_required)

Handle the normally-tricky “remember me” functionality.

Help protect your users’ sessions from being stolen by cookie thieves.

However, it does not:

Impose a particular database or other storage method on you. You are entirely in charge of how the user is loaded.

Restrict you to using usernames and passwords, OpenIDs, or any other method of authenticating.

Handle permissions beyond “logged in or not.”

Handle user registration or account recovery.

Get Started

  1. Install.
$ pip install flask-login
  1. Configuring a logging manager.
from flask_login import LoginManager
login_manager = LoginManager()

# register it to the flask app
login_manager.init_app(app)
  1. A user_loader() must be provided.
@login_manager.user_loader
def user_loader(user_id):
    return db.session.get(User, user_id)
  1. Use anotation @login_require if you want to protect the endpoint.
@login_required
def logout():
    logout_user()
    flash("You have been logged out.")
    return redirect(url_for("home"))

Note

You should put @login_required under the endpoint route definition, otherwise the login_required cannot work.

DO THIS

@popular_bp.route("/")
@login_required
def popular():
    """Render the popular page."""
    return render_template("popular.html")

DO NOT DO THIS

@login_required
@popular_bp.route("/")
def popular():
    """Render the popular page."""
    return render_template("popular.html")

And in java springboot, we never need to worry about the order of thses annotations.

Flask WTF

Flask-WTF provides your Flask application integration with WTForms.

Create Forms

from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired

class MyForm(FlaskForm):
    name = StringField('name', validators=[DataRequired()])

CSRF

<form method="POST" action="/">
    {{ form.csrf_token }}
    {{ form.name.label }} {{ form.name(size=20) }}
    <input type="submit" value="Go">
</form>

Validating Forms

@app.route('/submit', methods=['GET', 'POST'])
def submit():
    form = MyForm()
    if form.validate_on_submit():
        return redirect('/success')
    return render_template('submit.html', form=form)

Note that you don’t have to pass request.form to Flask-WTF; it will load automatically. And the convenient validate_on_submit will check if it is a POST request and if it is valid.

{% if form.name.errors %}
    <ul class="errors">
    {% for error in form.name.errors %}
        <li>{{ error }}</li>
    {% endfor %}
    </ul>
{% endif %}

Flask Flash

Flask flashing is a feature that allows developers to send messages to users, usually in response to some user action. These messages are often used to inform users about the success or failure of a particular operation or to provide feedback about the system’s status.

Using Flask flashing, we can send messages of different types, such as success, error, warning, and info messages. Flask flashing is a simple way to provide users with feedback about their actions on the website.

Use Flash in the project

  1. Call a flash(message, category) function in your code, mostly in the routes.
@auth_bp.route("/logout")
@login_required
def logout():
    """Log out the user."""
    logout_user()
    flash("You have been logged out.", "alert-success")

    return redirect(url_for("auth.auth"))
  1. The flash message will render in the layout.html.
{% with messages = get_flashed_messages(with_categories=true) %} 
  {% if messages %} 
    {% for category, message in messages %}
      <div
        id="alert"
        class="sticky-top alert {{ category }} alert-dismissible text-center fade show"
        role="alert"
      >
        {{ message }}
        <button
          type="button"
          class="btn-close"
          data-bs-dismiss="alert"
          aria-label="Close"
        ></button>
      </div>
    {% endfor %}
 {% endif %} 
{% endwith %}
  1. We use the flash.category to decide what alert class you want in the layout.html, as we use bootstrap alert to show the message. So When you want to flash a message, you should choose the category value from the list below:
  • "alert-primary"
  • "alert-secondary"
  • "alert-success"
  • "alert-danger"
  • "alert-warning"
  • "alert-info"
  • "alert-light"
  • "alert-dark"
  1. Use the FlashAlertTypeEnum in constant.py for the alert types.

Flask Migrate

Description: The function of migrate setting is that it can save db status / take snap shot to make it don't need to create/delete everytime the app restarted so that the app can keep the test data.

  1. init database snapshot, to creat the env. If you want creat your own database, delete the /migrations folder.

flask db init

  1. after changing the database structure. do this first. Then it is stored the database structure snapshot into the /migrations/versions/.

flask db migrate -m "random comment here"

  1. after we handle the last step, we can see the linked list by

flask db history

  1. we can also see where our current location is by current

flask db current

image

  1. upgrade/downgrade means to move forwards/backwards to the next node which will make the database structure changes to the state of at the time running step2. The data which is relevant to the change will be delete.

flask db upgrade

flask db downgrade

Clone this wiki locally