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:
flask
The directory where static files are stored - Templates (template) :
flask
The directory in which the page template is stored - Services: Stores business logic or other service functions
- init.py:
flask
App 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 to
URL
The prefix and/
Or subdomain, register a blueprint on the app.URL
The prefix/
Parameters in the subdomain become view parameters common to all view functions under the blueprint (by default) - Different in one application
URL
Rules 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 one
Flask
When 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.