Study_microblog notes Part 7 -- Application Architecture reconstruction with blueprint

As a project, we should always consider how the flash application will not become chaotic and difficult to manage in the continuous growth. I will try some patterns suitable for large applications, and in order to demonstrate them, I will make some changes to the structure of the Microblog project, with the goal of making the code easier to maintain and organize.

1, blueprint

blueprint is used to distinguish the mixed view functions, forms and templates according to different functional modules, so as to improve the reusability.
The structure is as follows:

User authentication Blueprint:

In order to create this blueprint, all authentication related functions are moved to the new module created for blueprint. This includes some view functions, Web forms, and support functions. Move the templates to a subdirectory to separate them from the rest of the application.
Creating a blueprint is very similar to creating an application. This is in blueprint___ init__. Completed in py module:
app/auth/init.py:

from flask import Blueprint

bp=Blueprint('auth',__name__)

from app.auth import routers

When defining a route in blueprint, use @ BP Route decorator instead of @ app Route decorator. At URL_ The syntax used to build URLs in for () also needs to be changed. For regular view functions attached directly to the application, the URL_ The first argument to for () is the name of the view function. However, when defining a route in blueprint, the parameter must contain the blueprint name and the view function name, separated by a period. Use such as URL_ The code for ('auth.login ') replaces all URLs that appear_ For ('login ') code, the same is true for other view functions.

app/auth/routers.py:

from flask import render_template,flash,redirect,url_for,request
from app import app,db
from app.auth.forms import LoginForm,RegistrationForm
from app.models import User
from flask_login import current_user,login_user,logout_user,login_required
from werkzeug.urls import url_parse
from app.auth import bp

# ...

@bp.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Congratulations, you are now a registered user!')
        return redirect(url_for('auth.login'))
    return render_template('auth/register.html', title='Register', form=form)



@bp.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))


@bp.route('/login', methods=['GET', 'POST'])
def login():

    if current_user.is_authenticated:
        return redirect(url_for('index'))

    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('auth.login'))
        login_user(user, remember=form.remember_me.data)
        next_page = request.args.get('next')
        if not next_page or url_parse(next_page).netloc != '':
            next_page = url_for('index')
        return redirect(next_page)

    return render_template('auth/login.html', title='Sign In', form=form)

app/init.py: register user authentication blueprint to the application.

# ...
from app.auth import bp as auth_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
# ...

register_ The blueprint () call received an additional parameter, url_prefix. This is completely optional. Flask provides the option to add a URL prefix to the route of blueprint, so any route defined in blueprint will get this prefix in its full URL. In many cases, this can be used as a "namespace", which can separate all routes in blueprint from other routes in application or other blueprint.

Main application Blueprint

Similar to user registration blueprint /.
app/main/init.py:

from flask import Blueprint

bp=Blueprint('main',__name__)

from app.main import routers

app/main/routers.py:

from flask import render_template
from app import app
from app.main import bp

from flask_login import login_required




@bp.route('/')
@bp.route('/index')
@login_required
def index():
    # user = {'username': 'Miguel'}
    posts = [
        {
            'author': {'username': 'John'},
            'body': 'Beautiful day in Portland!'
        },
        {
            'author': {'username': 'Susan'},
            'body': 'The Avengers movie was so cool!'
        }
    ]
    return render_template('index.html', title='Home', posts=posts)

In APP / init Register in py:

# ...
from app.main import bp as main_bp
app.register_blueprint(main_bp,)
# ...

Now try it!

Keywords: Python

Added by paulb on Tue, 01 Feb 2022 14:49:27 +0200