如何将以下Python代码改造为模块?
How to Refactor Your Flask Code into a Modular Structure
Hey, let's break down your monolithic Flask code into a clean, modular structure—this makes it way easier to maintain, scale, and debug. Here's a step-by-step approach:
1. Project Structure Setup
First, organize your files into a logical hierarchy. This is a standard layout for small-to-medium Flask apps:
my_flask_app/ ├── app/ │ ├── __init__.py # App initialization & core extensions │ ├── models.py # Database models (User, etc.) │ ├── forms.py # WTForms definitions │ ├── routes.py # All route functions │ └── templates/ # Your HTML templates (login.html, home.html, etc.) ├── config.py # App configuration (secrets, DB URI) └── run.py # Entry point to start the app
2. Split Code into Modules
config.py – Centralized Configuration
Keep sensitive/changeable settings separate from your core code:
import os class Config: # Use environment variables for production, fallback to a local secret for dev SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-dev-secret-key-here' SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///site.db' SQLALCHEMY_TRACK_MODIFICATIONS = False # Disable unnecessary overhead
app/__init__.py – Initialize Core Components
Set up your Flask app, database, login manager, and bootstrap here:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from flask_bootstrap import Bootstrap from config import Config # Initialize Flask app app = Flask(__name__) app.config.from_object(Config) # Initialize extensions db = SQLAlchemy(app) login_manager = LoginManager(app) login_manager.login_view = 'login' # Route to redirect unauthenticated users bootstrap = Bootstrap(app) # Import routes and models to register them with the app from app import routes, models
app/models.py – Database Models
Move your User model here to keep database logic isolated:
from app import db from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, nullable=False) password_hash = db.Column(db.String(128), nullable=False) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password)
app/forms.py – WTForms Definitions
Extract form classes to their own module for clarity:
from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, Length, ValidationError from app.models import User class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)]) password = PasswordField('Password', validators=[DataRequired()]) submit = SubmitField('Login') class RegistrationForm(FlaskForm): username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)]) password = PasswordField('Password', validators=[DataRequired()]) submit = SubmitField('Register') # Custom validator for unique usernames def validate_username(self, username): user = User.query.filter_by(username=username.data).first() if user is not None: raise ValidationError('Please choose a different username.')
app/routes.py – Route Functions
All your view logic goes here, keeping it separate from setup code:
from flask import render_template, redirect, url_for, flash from flask_login import login_user, logout_user, current_user, login_required from app import app, db from app.forms import LoginForm, RegistrationForm from app.models import User @app.route('/') @app.route('/home') def home(): return render_template('home.html') @app.route('/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: return redirect(url_for('home')) form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user is None or not user.check_password(form.password.data): flash('Invalid username or password') return redirect(url_for('login')) login_user(user) return redirect(url_for('home')) return render_template('login.html', title='Login', form=form) @app.route('/logout') def logout(): logout_user() return redirect(url_for('home')) @app.route('/register', methods=['GET', 'POST']) def register(): if current_user.is_authenticated: return redirect(url_for('home')) form = RegistrationForm() if form.validate_on_submit(): user = User(username=form.username.data) user.set_password(form.password.data) db.session.add(user) db.session.commit() flash('Congratulations, you\'re now a registered user!') return redirect(url_for('login')) return render_template('register.html', title='Register', form=form)
run.py – App Entry Point
A simple file to start your app:
from app import app, db if __name__ == '__main__': # Create database tables if they don't exist with app.app_context(): db.create_all() app.run(debug=True)
3. Key Benefits of This Structure
- Separation of Concerns: Each module handles one job (config, models, forms, routes) making code easier to navigate.
- Scalability: As your app grows, you can add more modules (like
blueprintsfor larger route sets,utils.pyfor helper functions) without cluttering existing code. - Security: Sensitive settings (like
SECRET_KEY) are kept out of core code and can be loaded from environment variables in production. - Testability: You can test individual modules (e.g., models or forms) independently of the full app.
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

