Flask 快速搭建模板1

news/2025/3/18 14:56:37/文章来源:https://www.cnblogs.com/tzyuan123/p/18341777
  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.pypause

main.py

点击查看代码
import datetimefrom 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 RegisterFormform = RegisterForm()if form.validate_on_submit():username = form.username.datapassword = form.password.dataif 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 LoginFormform = 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 = FalseBOOTSTRAP_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 ValidationErrorclass 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%}

 

 

[代码下载](https://files.cnblogs.com/files/tzyuan123/simple_flask.rar?t=1722755727&download=true "代码下载")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/777731.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DubboNacos

Dubbo的前世今生 2011年10月27日,阿里巴巴开源了自己的SOA服务化治理方案的核心框架Dubbo,服务治理和SOA的设计理念开始逐渐在国内软件行业中落地,并被广泛应用。早期版本的dubbo遵循SOA的思想,是面向服务架构的重要组件。如今版本的Dubbo作为Spring Cloud的二进制通信方案…

c语言其三

返回值 8位—al 16位—ax 32位—eax 64位—eax(放低位,edx(高位 64: 32:1、char(两个字节)类型的返回值 2、short(两个字节) 类型的返回值 3、int (八个字节)类型的返回值 参数传递无论是char还是short类型,反汇编中都是以4个字节传递 结论:整数类型的参数…

ArkTS #02# Ability的调用及启动模式

1调用&单实例 import common from @ohos.app.ability.common import Want from @ohos.app.ability.Want @Entry @Component struct Index {@State message: string = Hello Worldbuild() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)Bu…

VMware虚拟机版OpenCore引导,Vmware安装苹果系统

使用Windows下的VMware虚拟机安装macOS系统,常规安装都需要使用到unlocker解锁工具.而直接使用OpenCore引导安装,就可以不使用unlocker解锁工具也能安装macOS系统,使用OpenCore引导的优点还是有的,比如改三码或五码还是比较方便,这里将最近配置的OpenCore引导分享给大家一起研究…

开发在线客服系统新的宣传推广站【微客客服】

打造一个软件宣传官网,这事儿可不简单。咱们得先搞清楚,这个网站要给谁看,要传达啥信息,需要哪些功能。我们网站是宣传【在线客服系统】的,所以需要把主要功能展示清楚 在线网址:https://weikefu.com.cn然后,咱们得设计一番,把网站的布局、界面和用户体验给搞定。接下来…

Java - 异常与File

异常灵魂四问:如果try中没有遇到问题,怎么执行?try全部执行,catch不执行如果try中可能会遇到多个问题,怎么执行?写多个catch与之对应,父类异常需要写在下面如果try中遇到的问题没有被捕获,怎么执行?异常会默认交给虚拟机处理,try...catch白写如果try中遇到了问题,那…

费马点(到三角形顶点之和最小的点)

2024_8_4 费马点(到三角形顶点之和最小的点) 1.如果有度数大于120的角,则该点为费马点。 2.否则为某条边为底边往外作正三角形,将外面的点与这条边以外的那个点连线就为最短长度。 \[f(X, \, Y, \, Z) = \sqrt{\frac{a^2+b^2+c^2+4\sqrt{3}S}{2}}. \]

ComfyUI插件:ComfyUI layer style 节点(四)

前言: 学习ComfyUI是一场持久战,而ComfyUI layer style 是一组专为图片设计制作且集成了Photoshop功能的强大节点。该节点几乎将PhotoShop的全部功能迁移到ComfyUI,诸如提供仿照Adobe Photoshop的图层样式、提供调整颜色功能(亮度、饱和度、对比度等)、提供Mask辅助工具、…

ABC365

A link题目已经说的很明白了,判断即可。点击查看代码 #include<bits/stdc++.h>using namespace std;int y;signed main(){cin >> y;if(y%4 != 0) cout << 365;else if(y%4 == 0&&y%100 != 0) cout << 366;else if(y%100 == 0&&y%400 …