Hardware and software Environment

  • windows 10 64bit
  • Anaconda3 with python 3.7
  • Pycharm 2020.1.2
  • Flask 1.1.2

The project structure

preface

In our example, all python code except the template file is written in the same PY file, which contains the view functions, database model, application configuration, and so on. In a small example, this is fine, but in a real project, it certainly won’t work.

The project structure

Flask is a lightweight Web framework that is extensible, flexible and easy to use. However, Flask does not give you a clear project structure. Instead, it lets developers create their own project structure based on actual needs. It should be noted that the project structure introduced in this paper may not be the best, but only a reference. Different projects, different teams and different ideas will have different project structures

project/
  forms/
    myform.py
    ...
  models/
    __init__.py
    mymodel.py
    ...
  routes/
    __init__.py
    myroute.py
    ...
  static/
    ...
  services/
    __init__.py
    ...
  templates/
    index.html
    ...
  __init__.py
  config.py
  manage.py
Copy the code

Among them

  • Forms: Holds a form object
  • Models: Stores the data model, that is, the objects that the library tables map to in the program and the relationships between the objects
  • Routes: Stores the request route and processing logic
  • Static file:flaskThe directory where static files are stored
  • Templates (template) :flaskThe directory in which the page template is stored
  • Services: Stores business logic or other service functions
  • init.py: flaskApp initialization method
  • Config. py: project configuration file
  • Manage.py: Start a development server, but will not be used in production

The blueprint

What is a blueprint

Blueprint provides the function of modularizing hypervisor routing, making the program structure clear and easy to understand. Blueprint objects and Flask application objects work much like each other, but they are not the same thing. Blueprints nicely simplify the way large applications work and provide the core method for flask extensions to register operations on applications.

Apply the factory function

The common Flask project structure mentioned earlier is that it is convenient to develop applications in a single file, but the big disadvantage is that applications are created in a global scope and cannot be configured dynamically. After the application instance is created, it is too late to modify the configuration. The solution to this problem is to delay the creation of the application instance, where the factory function comes into play, as shown in the following example

from flask import Flask
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from app.config import Config

bootstrap = Bootstrap()
db = SQLAlchemy()

def create_app(config_class=Config) :
    app = Flask(__name__)
    app.config.from_object(Config)
    bootstrap.init_app(app)
    db.init_app(app)

    return app
Copy the code

Most of the Flask extensions in use are imported first, but since the required application instances have not yet been initialized, no arguments are passed to the constructor when the extension class is created, so the extension is not really initialized. The create_app function is the application’s factory function and takes one parameter, which is the name of the configuration used by the application. The configuration class is defined in the config.py file. Once the application is created and configured, you can initialize the extension. Initialization is done by calling init_app() on the previously created extension object

Why use blueprints

Look at the benefits of blueprints, from official documentation

  • Decompose an application into a collection of blueprints. This is ideal for large applications. A project can instantiate an application object, initialize several extensions, and register a collection of blueprints
  • In order toURLThe prefix and/Or subdomain, register a blueprint on the app.URLThe prefix/Parameters in the subdomain become view parameters common to all view functions under the blueprint (by default)
  • Different in one applicationURLRules register a blueprint multiple times
  • Provides template filters, static files, templates, and other functionality through blueprints. A blueprint does not have to implement applications or view functions.
  • Initialize oneFlaskWhen extending, register a blueprint in these cases

Blueprints act as a flask layer to provide an alternative to segmentation, sharing application configurations, and changing registered application objects if necessary. The downside is that you can’t unregister a blueprint after the application is created without destroying the entire application object.

A blueprint for the sample

With the application factory and blueprints above, let’s take a look at the example. The project structure is as follows

blueprint/
  app/
      static/
        ...

      views/
        index.py

      templates/
        ...

      __init__.py

      config.py

  manage.py
  README.md
  requirements.txt
Copy the code

The manage.py code is shown below

from app import create_app

if __name__ == '__main__':
    app = create_app()
    app.run(use_reloader=True, port=5000)
Copy the code

The __init__.py code is as follows

from flask import Flask
from .views.index import index_blueprint
from . import config


def create_app() :
    app = Flask(__name__)
    app.config.from_object(config)
    app.register_blueprint(index_blueprint)

    return app
Copy the code

The source code for index.py is as follows

from flask import Blueprint

index_blueprint = Blueprint('index', __name__)

@index_blueprint.route('/')
def index() :
    return "Hello blueprint."
Copy the code

Config.py stores the relevant configuration information

DEBUG = False
Copy the code

When the above project is started, we can access http://127.0.0.1:5000 and the browser outputs Hello Blueprint.

How to organize blueprints

Flask also has no rules about how you organize blueprints. Commonly, there are two ways to organize by function and divisional.

In a functional architecture, organize your application according to the functionality of each part of the code. All templates, static files, and views are placed in a separate folder, as shown below

project/
    app/
        __init__.py
        static/
        templates/
            home/
            admin/
        views/
            __init__.py
            home.py
            admin.py
        models.py
        config.py

    README.md
    requirements.txt
    manage.py
Copy the code

With the exception of project/app/views/__init__.py, every.py file in the project/app/views/ folder is a blueprint. In project/app/__init__.py, load these blueprints and register them in the flask object.

In a partitioned architecture, you organize your application according to the blueprint that each part belongs to. All templates, views, and static files are in one folder. The project structure is as follows

project/
    app/
        __init__.py
        admin/
            __init__.py
            views.py
            static/
            templates/
        home/
            __init__.py
            views.py
            static/
            templates/
        models.py
        config.py

    README.md
    requirements.txt
    manage.py
Copy the code

In the partitioned structure above, each folder under Project /app/ is a separate blueprint. All blueprints are registered with the top-level __init__.py into the flask object.

As for which of the two structures is better, there is no agreement. The general advice goes like this:

  • Partitioned applications are recommended if the application consists of independent components that share only the model and configuration.
  • A functional architecture is recommended if the components of your application are closely interconnected.