Flask 快速搭建模板1

  1. 快速搭建基础框架
    成品预览


pip安装

需要导入的基础包

pip install flask
pip install flask-sqlalchemy
pip install flask-wtf
pip install bootstrap-flask
pip install flask-login
pip install flask-moment

创建目录结构

type nul > main.py
type nul > config.py
type nul > models.py
type nul > forms.py
type nul > run.bat
md templates
md static
type nul > templates\base.html

run.bat

点击查看代码
root_path=%~dp0
echo current dir: %root_path%
cd %root_path%
call %root_path%.venv\Scripts\activate.bat
python main.py

pause

main.py

点击查看代码
import datetime

from flask import Flask, flash, redirect, render_template, url_for, request
from werkzeug.security import generate_password_hash, check_password_hash
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap4
from flask_login import LoginManager, current_user, login_user, logout_user, UserMixin,login_required
from flask_moment import Moment
from config import Config

# 创建app 实例
app = Flask(__name__)
app.config.from_object(Config)

# 定义扩展插件
db = SQLAlchemy(app)
bootstrap = Bootstrap4(app)
login_manager = LoginManager(app)
moment = Moment(app)

# 初始化
# db.init_app(app)
# bootstrap.init_app(app)
# login_manager.init_app(app)
login_manager.login_view = 'login'
# moment.init_app(app)


# 数据库定义
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30))
    password_hash = db.Column(db.String(128))
    create_time = db.Column(db.DateTime)
    status = db.Column(db.String(10))

    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)


@login_manager.user_loader
def load_user(userid):
    return User.query.get(userid)


# 路由
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
    return render_template('index.html')


@app.route('/view')
@login_required
def view():
    return render_template('view.html')

# 注册
@app.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    from forms import RegisterForm
    form = RegisterForm()
    if form.validate_on_submit():
        username = form.username.data
        password = form.password.data
        if User.query.filter_by(username=username).first():
            flash("用户已存在")
            return redirect(url_for('register'))
        user = User(username=username, create_time=datetime.datetime.now())
        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        flash("创建用户成功,请登录后使用")
        return redirect(url_for('login'))
    return render_template('register.html', form=form)


# 登录
@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    from forms import LoginForm
    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('无效的用户或者密码')
            return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)
        next_page = request.args.get('next')
        # if not next_page or url_parse(next_page).netloc != '':
        if not next_page:
            next_page = url_for('index')
        return redirect(next_page)
    return render_template('login.html', title="登录", form=form)


@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))


if __name__ == '__main__':
    # # 初始化数据库
    # with app.app_context():
    #     db.create_all()
    app.run(host='127.0.0.1', debug=True, port=1234)

config.py

点击查看代码
import os
import sys

# SQLite URI compatible
WIN = sys.platform.startswith('win')
if WIN:
    prefix = 'sqlite:///'
else:
    prefix = 'sqlite:////'
basedir = os.path.abspath(os.path.dirname(__file__))


class Config:
    SECRET_KEY = "1234567890"
    SQLALCHEMY_DATABASE_URI = prefix + os.path.join(basedir, 'data.db')
    print(f"ttt: {SQLALCHEMY_DATABASE_URI}")
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    BOOTSTRAP_SERVE_LOCAL = True

forms.py

点击查看代码
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField, BooleanField
from wtforms.validators import DataRequired, Length, EqualTo
from wtforms import ValidationError


class RegisterForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired(), Length(1, 30)])
    password = PasswordField('密码', validators=[DataRequired()])
    re_password = PasswordField('再次输入密码',
                                validators=[DataRequired(), EqualTo('password', message="两次输入的密码不一致")])
    submit = SubmitField("注册")

    # def validate_username(self, username):
    #     from main import User
    #     user = User.query.filter_by(username=username.data).first()
    #     if user is not None:
    #         raise ValidationError('用户已存在')


class LoginForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired(), Length(1, 30)])
    password = PasswordField('密码', validators=[DataRequired(), Length(1, 30)])
    remember_me = BooleanField('记住我')
    submit = SubmitField("登录")

base.html

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    {% block head %}
    <meta charset="UTF-8">
    <title>Title</title>
    {% block css %}
    {{ bootstrap.load_css() }}
    <link rel="stylesheet" href="{{ url_for('static', filename='base.css') }}">
    {% endblock css %}
    {% endblock head %}
</head>
<body>
{% block body %}
{% if request.endpoint not in ['login','register'] %}
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand" href="{{ url_for('index') }}">MyTools</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
                <a class="nav-link" href="{{ url_for('index') }}">首页 <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">特性一</a>
            </li>
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-expanded="false">
                    特性二
                </a>
                <div class="dropdown-menu">
                    <a class="dropdown-item" href="#">子特性一</a>
                    <a class="dropdown-item" href="#">子特性二</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="#">子特性三</a>
                </div>
            </li>
            <li class="nav-item">
                <a class="nav-link disabled">特性三</a>
            </li>
        </ul>

        <div class="text-center">
            {% if current_user.is_anonymous %}
            <a href="{{ url_for('register') }}">注册</a>
            {% else %}
            <h4 class="text-light"><strong>Hi,&nbsp;{{ current_user.username }}</strong></h4>
            {% endif %}
        </div>
        <div>
            <span> &nbsp;&nbsp;&nbsp;</span>
        </div>
        <div>
            {% if current_user.is_anonymous %}
            <a href="{{ url_for('login') }}">登录</a>
            {% else %}
            <a href="{{ url_for('logout') }}">退出</a>
            {% endif %}
        </div>
    </div>
</nav>

{% endif %}
<div class="container">
    <div class="row justify-content-end">
        {% for message in get_flashed_messages() %}
        <div class="alert alert-danger alert-dismissible fade show col-5 float-right" role="alert">
            {{ message }}
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        {% endfor %}
    </div>

    <main>
        {% block main %}
        {% endblock main %}
    </main>
</div>
<footer>
    {% block footer %}
    {% endblock footer %}
</footer>
{% block scripts %}
{{ bootstrap.load_js() }}
<script>
    $('.alert1').alert('close')
</script>
{% endblock scripts %}
{% endblock body %}
</body>
</html>

index.html

点击查看代码
{% extends 'base.html' %}
{% block main %}

<h1 class="h3 mb-3 font-weight-normal">Index</h1>

{% endblock main%}

register.html

点击查看代码
{% extends 'base.html' %}
{% from "bootstrap/form.html" import  render_form %}
{% block css %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='login.css') }}">
{% endblock css %}
{% block main %}
<div>
    <div class="row justify-content-center">
        <div class="col-4">
            <h1 class="h3 mb-3 font-weight-normal">用户注册</h1>
            {{ render_form(form, action=request.full_path,horizontal_columns=('lg', 2, 4)) }}
        </div>
    </div>
</div>
{% endblock main%}

login.html

点击查看代码
{% extends 'base.html' %}

{% block css %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='login.css') }}">
{% endblock css %}

{% block main %}
<form class="form-signin" method="post">
    <h1 class="h3 mb-3 font-weight-normal">欢迎使用,请登录</h1>
    <h6 class="h6 mb-3 font-weight-normal">没有账户,请<a href="{{ url_for('register') }}">注册</a></h6>
    {{ form.csrf_token }}
    {{ form.username.label(class="sr-only") }}
    {{ form.username(class="form-control", placeholder="用户名",required="required",autofocus="autofocus") }}
    {% for message in form.username.errors %}
    <small class="error">{{ message }}</small><br>
    {% endfor %}
    {{ form.password.label(class="sr-only") }}
    {{ form.password(class="form-control",placeholder="密码",required="required") }}
    {% for message in form.password.errors %}
    <small class="error">{{ message }}</small><br>
    {% endfor %}
    <div class="checkbox mb-3">
        <label>
            {{ form.remember_me }} {{ form.remember_me.label }}
        </label>
    </div>
    {{ form.submit(class="btn btn-lg btn-primary btn-block") }}
</form>
{% endblock main%}

 

 

代码下载

posted @ 2024-08-04 15:31  糖果糖果  阅读(2)  评论(0编辑  收藏  举报