Commands¶
flask new¶
After installing Flask-Commands globally, you’ll have access to a new command called flask, which lets you quickly scaffold Flask applications from the terminal.
To create a new project named myproject, run:
flask new myproject
Once the command completes, you’ll see a new directory called myproject/. This directory contains everything you need to get a Flask application up and running.
During the installation process you will be prompted to include a SQLite Database.
Include a SQLite Database? [Y/n]:
If you press enter without typing anything the default setting of yes will apply. If you type n and press enter then the project will load as normal; however, you will not get a models folder and a few python dependances will not be installed. A use case for this is if you are developing a static site that does not customize the user’s experience.
What you get¶
The generated project includes a clean, opinionated structure with sensible defaults:
A Python virtual environment
venv/with core Flask dependencies pre-installed and listed inrequirements.txt.- When using –db (enabled by default unless –no-db is specified as an option with the new command), the following are also included:
Flask-Migrate
Flask-SQLAlchemy
A seeded SQLite database with a users table
An initial migration already applied
- A Blueprint-based application skeleton under
app/, organized by responsibility: Model
app/models/Defining all your applications data models/structure along with their methods.View
app/templates/Containing all HTML templates (including macros/components) used by the application.Controller
app/controllers/Housing controller classes responsible for the logic to gather and serve the requested data.URL
app/routes/Declaring and naming URL paths and connects them to controllers.
- A Blueprint-based application skeleton under
The project entry point at
run.pyCentralized configuration files under
config/If npm is installed on your machine then a Tailwind ready static asset pipeline located at
app/static/src/, including npm scripts for watching and building CSS- Environment configuration files:
.env.env.example
- A default Blueprint named
mains, defined inapp/__init__.py Routes located at
app/routes/mainsA controller at
app/controllers/main_controllernamedMainControllerA starter “Hello World” template at
app/templates/mains/index.html
- A default Blueprint named
A macOS-friendly helper script run.sh for starting the application with a single command:
./run.sh
You can review this structure directly in the Flask-Commands source by exploring the files and folders under:
flask_commands/project
flask make:view¶
Now for the fun (and powerful) part of this package. First make sure you are at the root of your new project.
The flask make:view command generates template files under app/templates/.
It supports dot notation for nested folders. For example, posts.index creates:
app/templates/posts/index.html
While creating template files is great fun templates themselve don’t do
much on their own unless they are rendered by a route and a controller
class. To make that wiring easier, flask make:view includes optional
generator flags:
-c / --generate-controlleror--controller NAMECreates (or extends) a controller class in your application.-r / --generate-routeor--route PATHAdds blueprint routes and supports the seven RESTful actions:index,show,create,store,edit,update,destroy(ordeleteif you prefer).-m / --generate-modelor--model NAMESeeds a SQLAlchemy model with boilerplate columns:id,created_at, andupdated_at.
Let’s work through a few examples, starting with the basics and ending with nested relationships using RESTful actions.
No Dot Examples¶
Suppose you want an about view for your company:
flask make:view about
That’s it — you now have a new template at app/templates/about.html.
The issue is that this page is not appearing in your application. You can’t just
type /about or about.html into the browser and expect it to work because
the view is not wired up to a route or controller class.
Adding a Route and Controller (Explicit)¶
To solve the above issue, we can explicitly tell the command to wire up a route and controller class:
flask make:view about --route /about --controller MainController
In this example, MainController is used because a fresh application ships
with a MainController and a blueprint named mains.
This command:
creates
app/templates/about.htmladds an
aboutmethod to theMainControllerclass (app/controllers/main_controller.py)updates the
mainsroutes file (app/routes/mains/routes.py) with aGETroute at/about
This works great — but it’s a lot of typing 😵💫. Don’t worry, in come the
generator flags -r and -c (or combined as -rc).
Adding a Route and Controller (Generators)¶
The same result as above, using generator flags:
flask make:view about -rc
Much shorter and easy to remember just think i need to wire this up with a route (url) and have the controller serve the page. So route is the r and controller is the c
Nesting Views¶
The view name uses dot notation to represent nested structures.
If you want to create reusable component views, you might keep them in
a components directory. To do this, just prefix the view name
with components.:
flask make:view components.accordions
flask make:view components.checkboxes
flask make:view components.selects
These commands create:
app/templates/components/accordions.htmlapp/templates/components/checkboxes.htmlapp/templates/components/selects.html
You might use these files to house reusable macros. Notice that these views are not wired up to any controller class or route because we didn’t specify any generator flags.
In the about example from Adding a Route and Controller (Generators) I
would actually nest this because mains has it’s own folder in
templates. To keep you templates folder nice and tidy I would have used
the command:
flask make:view mains.about -rc
but we didn’t know about nesting at the time (now we do).
Adding Models¶
Nesting becomes essential when you start building out models.
For applications that use a database (SQLite, MySQL, PostgreSQL, …), views are
often tied directly to models. Flask-Commands follows the seven RESTful
actions:
indexshowcreatestoreeditupdatedestroy(ordelete— frankly, I would have called itnuke😜)
If you’re new to these actions (or just need a refresher), here’s a quick review of what each one does and which HTTP method it uses.
There are other HTTP methods (PUT, PATCH, DELETE), but browsers traditionally only understand GETs and POSTs. I always think of the browser lifecycle as:
Get → Post → Redirect
You get the page, you post a form, and then you redirect to a new page to give feedback about what just happened. We’ll look at this more closely when we discuss controller classes. For now, just familiarize yourself with the seven actions.
Action |
Method |
URL Example |
Behavior |
|---|---|---|---|
index |
GET |
/users |
Show all instances of a model |
show |
GET |
/users/<int:user_id> |
Show a single instance |
create |
GET |
/users/create |
Show the page to create a new instance |
store |
POST |
/users/create |
Create a new instance (then redirect) |
edit |
GET |
/users/<int:user_id>/edit |
Show the page to edit an instance |
update |
POST |
/users/<int:user_id>/edit |
Update an instance (then redirect) |
destroy |
POST |
/users/<int:user_id>/delete |
Delete an instance (then redirect) |
To demonstrate this let’s suppose you have a cooking website and you want to list all your recipes.
That’s the index action.
This means we need:
a
recipes.indexviewa
Recipemodela
RecipeControllercontroller class to handle the actions
To create the index page and wire up the route, controller, and model:
flask make:view recipes.index --route /recipes --controller RecipeController --model Recipe
This one command creates five files and updates three more 😮
Created files¶
app/templates/recipes/index.html— the recipes index viewapp/controllers/recipe_controller.py— the controller classapp/routes/recipes/__init__.py— the recipes blueprint packageapp/routes/recipes/routes.py— the recipes routes fileapp/models/recipe.py— the Recipe model
Updated files¶
app/controllers/__init__.py— registersRecipeControllerapp/models/__init__.py— registersRecipeapp/__init__.py— registers the recipes blueprint increate_app
Now you know why I wrote this package — that’s a lot to wire up just to get one model-backed view.
But wait it get’s better!!! The above is just to much to type so I shortened it to the command
flask make:view recipes.index -rcm
If you use -r, -c, and -m (in any order), Flask-Commands assumes the
standard setup above and does exactly the same thing.
To create the show page for a single recipe, you could write:
flask make:view recipes.show --route /recipes/<int:recipe_id> --controller RecipeController
Or, using the generators:
flask make:view recipes.show -rc
Notice we didn’t include -m here because the model already exists. In this
case, the only new file is the view template — the route and controller class
are updated in place. If you forgot and added the -m then you would have received a warning saying that the recipe model already exists and was left alone (which is what you want expecally if you have gone in and made changes to the model)
Nesting Models¶
This is were the packages really shine! Let’s continue with our recipe website example and suppose that we are going to allow users to make comments on the recipes. This is an example of a one to many relationship (a single recipe might have many comments). First let’s write out the long command to understand what we need and then we will provide the shortened version.
flask make:view recipes.comments.index -rcm