I. What is Flask?¶
Flask is a lightweight Python Web framework that implements the core functionality of web applications with concise code while maintaining high flexibility. Unlike Django’s “batteries-included” philosophy, Flask is more like a “toolkit” where you can choose components (such as ORM, form handling, etc.) as needed. It is ideal for beginners to start web development and also suitable for quickly developing small-to-medium projects.
II. Development Environment Setup¶
1. Install Python¶
First, ensure Python (version 3.7+ is recommended) is installed on your computer:
- Check Installation: Open the terminal/command line and run python --version or python3 --version. If the version number is displayed, the installation is successful.
- Download Link: Python Official Website
2. Install Flask¶
Use Python’s package manager pip to install Flask:
pip install flask
Verify the installation: Open the Python interactive environment (python or python3) and run import flask. No error messages indicate a successful installation.
III. Project Development Process¶
1. Create a Virtual Environment (MANDATORY!)¶
To avoid dependency conflicts between different projects, it is recommended to create an independent virtual environment for each project:
- Create a Virtual Environment (Python 3.3+ has the built-in venv module):
python -m venv myflaskenv # Works on Windows/Linux/Mac
- Activate the Virtual Environment:
- Windows (Command Prompt):
myflaskenv\Scripts\activate - Linux/Mac (Terminal):
source myflaskenv/bin/activate
After activation, the terminal prefix will show(myflaskenv), indicating the environment is active.
2. Initialize Project Structure¶
A good project structure makes code easier to maintain. The recommended basic structure is:
myflaskapp/ # Project root directory
├── app.py # Application entry point
├── requirements.txt # Dependency list (generate with: pip freeze > requirements.txt)
├── static/ # Static files (CSS/JS/images)
│ └── css/
│ └── style.css
└── templates/ # HTML templates
└── index.html
3. First “Hello World”¶
Write the basic code in app.py:
from flask import Flask # Import the Flask class
app = Flask(__name__) # Create an application instance (__name__ refers to the current module)
@app.route('/') # Define the route: the function below is executed when accessing the root path
def index(): # View function: handles requests and returns responses
return "Hello, Flask!" # Return a string
if __name__ == '__main__': # Executed when app.py is run directly
app.run(debug=True) # Start the development server (debug=True auto-restarts on code changes)
Run the application:
python app.py
Open a browser and visit http://127.0.0.1:5000/ to see “Hello, Flask!”.
4. Routing and Dynamic Parameters¶
Basic Routing¶
Besides the root path /, you can define other routes:
@app.route('/about')
def about():
return "About our project"
@app.route('/user')
def user_profile():
return "User profile page"
Dynamic Routing Parameters¶
To get parameters from the URL (e.g., user ID), use the <parameter> syntax:
@app.route('/user/<username>') # <username> in the URL is passed as a parameter to the function
def show_user(username):
return f"User: {username}" # Directly render the parameter
@app.route('/post/<int:post_id>') # <int:post_id> restricts the parameter to an integer
def show_post(post_id):
return f"Post ID: {post_id}"
5. Template System (Rendering HTML)¶
Flask uses the Jinja2 template engine by default. Create HTML files in the templates folder:
templates/index.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title> <!-- Variable rendering -->
</head>
<body>
<h1>{{ message }}</h1>
{% if is_logged_in %} <!-- Conditional judgment -->
<p>Welcome back!</p>
{% else %}
<p>Please log in first</p>
{% endif %}
<ul>
{% for item in items %} <!-- Loop through items -->
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
Render the template in app.py:
from flask import render_template # Import the template rendering function
@app.route('/page')
def page():
data = {
'title': 'Homepage',
'message': 'Welcome to Flask templates',
'is_logged_in': True,
'items': ['Item 1', 'Item 2', 'Item 3']
}
return render_template('index.html', **data) # Pass data to the template
Static File Reference: Use url_for('static', filename='path') in templates to reference CSS/JS/images:
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
6. Handling Forms and Data¶
Get Form Data¶
Use the request object to get user input (import first):
from flask import request, render_template, redirect, url_for
@app.route('/login', methods=['GET', 'POST']) # Allow both GET (display form) and POST (submit data)
def login():
if request.method == 'POST': # Check the request method
username = request.form.get('username') # Get the 'username' field from the form
password = request.form.get('password')
if username == 'admin' and password == '123456':
return redirect(url_for('dashboard')) # Redirect to the dashboard page
else:
return "Username or password is incorrect"
return render_template('login.html') # Display the form for GET requests
Simple Form Validation¶
Use flask.flash to provide feedback on operation results (e.g., login failure messages):
from flask import flash
@app.route('/login', methods=['POST'])
def login_post():
if not request.form.get('username'):
flash('Username cannot be empty', 'error') # Error message
return redirect(url_for('login'))
# ... Other validation logic
Display flash messages in the template:
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="{{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
7. Database Operations (Flask-SQLAlchemy)¶
Flask does not include built-in database functionality; use extensions. Here’s an example with SQLite (lightweight, no configuration needed):
Install Dependencies¶
pip install flask-sqlalchemy # ORM tool to simplify database operations
Initialize the Database¶
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.db' # SQLite database path
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Disable modification tracking (saves resources)
db = SQLAlchemy(app) # Initialize the ORM object
Define Data Models¶
class User(db.Model):
id = db.Column(db.Integer, primary_key=True) # Primary key
username = db.Column(db.String(80), unique=True, nullable=False) # Username
email = db.Column(db.String(120), unique=True, nullable=False) # Email
def __repr__(self):
return f'<User {self.username}>'
Create Tables and CRUD Operations¶
Execute the following commands in the Python interactive environment to create tables:
from app import app, db, User
with app.app_context(): # Application context (avoids runtime errors)
db.create_all() # Create all tables based on models
# Add a user
user = User(username='test', email='test@example.com')
db.session.add(user)
db.session.commit() # Commit the transaction
# Query users
users = User.query.all() # Query all users
user = User.query.filter_by(username='test').first() # Query a single user
# Delete a user
db.session.delete(user)
db.session.commit()
IV. Best Practices for Projects¶
1. Configuration Management¶
Avoid hardcoding configurations; separate them using environment variables or config.py:
Method 1: Environment Variables
import os
from dotenv import load_dotenv # Install with: pip install python-dotenv
load_dotenv() # Read the .env file
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') # Get the key from environment variables
app.config['DATABASE_URI'] = os.getenv('DATABASE_URI', 'sqlite:///default.db') # Default value
.env File (in the root directory):
SECRET_KEY=your_secret_key_here
FLASK_ENV=development
Method 2: Multi-Environment Configuration
Create config.py:
class Config:
SECRET_KEY = 'your_secret_key'
class DevelopmentConfig(Config):
DEBUG = True
DATABASE_URI = 'sqlite:///dev.db'
class ProductionConfig(Config):
DEBUG = False
DATABASE_URI = os.getenv('DATABASE_URI')
Load the configuration based on the environment:
app.config.from_object(DevelopmentConfig) # For development
# app.config.from_object(ProductionConfig) # For production
2. Code Structure and Blueprints¶
For larger projects, split functional modules (e.g., user module, order module) using Blueprints:
Create a Blueprint (e.g., users.py)¶
from flask import Blueprint, render_template
users_bp = Blueprint('users', __name__, url_prefix='/users') # Route prefix
@users_bp.route('/profile')
def profile():
return render_template('users/profile.html')
Register the Blueprint (in app.py)¶
from users import users_bp
app.register_blueprint(users_bp) # Register the blueprint
After using the blueprint, the access path becomes /users/profile.
3. Error Handling¶
Customize 404/500 pages to improve user experience:
@app.errorhandler(404)
def not_found(e):
return render_template('404.html'), 404 # Return status code 404
@app.errorhandler(500)
def server_error(e):
return render_template('500.html'), 500
4. Logging¶
Log key operations (e.g., login, errors) for easier debugging:
import logging
from logging.handlers import RotatingFileHandler
def setup_logging(app):
file_handler = RotatingFileHandler('app.log', maxBytes=10240, backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Flask application started')
# Call after app initialization
setup_logging(app)
5. Testing¶
Use pytest or Flask’s test client to verify functionality:
# Install pytest: pip install pytest
# test_app.py
import pytest
from app import app, db
@pytest.fixture
def client():
app.config['TESTING'] = True
with app.test_client() as client: # Test client
with app.app_context():
db.create_all()
yield client
db.drop_all() # Drop tables after testing
def test_login(client):
response = client.post('/login', data={'username': 'admin', 'password': '123'}, follow_redirects=True)
assert response.status_code == 200 # Assert login success (redirect to dashboard)
V. Deployment Introduction¶
After development, deploy the project to a server for public access:
1. Local Deployment¶
- Disable debug in production:
app.run(debug=False) - Use
gunicornas a WSGI server (more stable than Flask’s built-in server):
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app # 4 worker processes, bind to port 8000
2. Cloud Platform Deployment¶
- PythonAnywhere: Suitable for beginners, upload code + configure virtual environment.
- Heroku: Requires a
Procfilefile:
web: gunicorn app:app
And set environment variables: heroku config:set SECRET_KEY=xxx.
VI. Conclusion¶
The core of Flask is “lightweight and flexible”. To go from “Hello World” to a complete project, you need to master:
1. Basic routing and view functions
2. Template and static file management
3. Form handling and data validation
4. Database operations (SQLAlchemy)
5. Project structure (blueprints, configuration, logging)
Practice by developing simple projects (e.g., a blog, to-do app) to consolidate knowledge and gradually increase project complexity. Flask has strong extensibility; later, you can integrate extensions like Celery (asynchronous tasks) and Flask-RESTful (API development) to meet more complex needs.
Finally: Coding is the best way to learn. From imitation to independent development, you will gradually master the core logic of web development!