Like everything with Flask, there are many ways that we can organize our app using blueprints. With blueprints, we can think of the choice as functional versus divisional (terms I'm borrowing from the business world).
7.3.1. Functional structure
With a functional structure, you organize the pieces of your app by what they do. Templates are grouped together in one directory, static files in another and views in a third.
yourapp/ __init__.py static/ templates/ home/ control_panel/ admin/ views/ __init__.py home.py control_panel.py admin.py models.py
With the exception of yourapp/views/init.py, each of the .py
files in the yourapp/views/ directory from this listing is a
blueprint. In yourapp/init.py we would import those blueprints
and register them on our Flask()
object. We'll look a little more
at how this is implemented later in this chapter.
Note At the time of writing this, the Flask website at http://flask.pocoo.org uses this structure. Take a look for yourself on GitHub.
7.3.2. Divisional
With the divisional structure, you organize the pieces of the application based on which part of the app they contribute to. All of the templates, views and static files for the admin panel go in one directory, and those for the user control panel go in another.
yourapp/ __init__.py admin/ __init__.py views.py static/ templates/ home/ __init__.py views.py static/ templates/ control_panel/ __init__.py views.py static/ templates/ models.py
With a divisional structure like the app in this listing, each directory
under yourapp/ is a separate blueprint. All of the blueprints are
applied to the Flask()
app in the top-level init.py
7.3.3. Which one is best?
The organizational structure you choose is largely a personal decision. The only difference is the way the hierarchy is represented - i.e. you can architect Flask apps with either methodology - so you should choose the one that makes sense to you.
If your app has largely independent pieces that only share things like models and configuration, divisional might be the way to go. An example might be a SaaS app that lets user's build websites. You could have blueprints in "divisions" for the home page, the control panel, the user's website, and the admin panel. These components may very well have completely different static files and layouts. If you're considering spinning off your blueprints as extensions or using them for other projects, a divisional structure will be easier to work with.
On the other hand, if the components of your app flow together a little more, it might be better represented with a functional structure. An example of this would be Facebook. If Facebook used Flask, it might have blueprints for the static pages (i.e. signed-out home, register, about, etc.), the dashboard (i.e. the news feed), profiles (/robert/about and /robert/photos), settings (/settings/security and /settings/privacy) and many more. These components all share a general layout and styles, but each has its own layout as well. The following listing shows a heavily abridged version of what Facebook might look like it if were built with Flask.
facebook/ __init__.py templates/ layout.html home/ layout.html index.html about.html signup.html login.html dashboard/ layout.html news_feed.html welcome.html find_friends.html profile/ layout.html timeline.html about.html photos.html friends.html edit.html settings/ layout.html privacy.html security.html general.html views/ __init__.py home.py dashboard.py profile.py settings.py static/ style.css logo.png models.py
The blueprints in facebook/views/ are little more than collections of views rather than wholly independent components. The same static files will be used for the views in most of the blueprints. Most of the templates will extend a master template. A functional structure is a good way to organize this project.