首页 > 其他分享 >Flask 快速搭建模板1

Flask 快速搭建模板1

时间:2024-08-04 15:27:52浏览次数:12  
标签:username form Flask app user login password 模板 搭建

  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%}

 

 

代码下载

标签:username,form,Flask,app,user,login,password,模板,搭建
From: https://www.cnblogs.com/tzyuan123/p/18341777

相关文章

  • Flask 用户身份验证包括登录、注册和谷歌登录未集成在一起
    https://www.freecodecamp.org/news/how-to-setup-user-authentication-in-flask/我已经使用上面的链接进行了基本的用户身份验证,但我无法添加谷歌登录。我已经尝试了很多次,但我无法添加谷歌登录。任何人都可以帮我做这个吗?问题是有src_init_.py和man......
  • [附开题]flask框架高校资产管理系统d8y3s(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育事业的快速发展,高校资产规模日益庞大,种类繁多,管理难度显著增加。传统的资产管理方式往往依赖于手工记录和纸质档案,不仅效率低......
  • [附开题]flask框架贺州图特产管理系统uuy79(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景贺州,这座历史悠久、文化底蕴深厚的城市,以其丰富的自然资源和独特的地理位置孕育了众多令人瞩目的特产。然而,在信息化快速发展的今天,贺州特......
  • [附开题]flask框架红枫超市会员管理系统ew5iq(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着零售行业的快速发展与消费者需求的日益多样化,超市作为人们日常生活中不可或缺的一部分,其管理效率和服务质量直接影响着顾客的购物体验......
  • thinkphp.5.1环境配置搭建一个简易程序
    众所周知php是搭建应用程序简单快捷的语言,今天我们就搭建一下吧工具准备thinkphp框架源码:thinkphp:ThinkPHP是一个开源的,快速、简单的面向对象的轻量级PHP开发框架framework:ThinkPHP核心框架库代码管理工具(可选)sourtree之前我的博客中有详细介绍使用,这里不一一......
  • 五级分销版蝶影全网VIP影视 APP源码 安卓+苹果iOS双端+搭建教程
    ###五级分销版蝶影全网VIP影视APP源码安卓+苹果iOS双端+搭建教程在数字娱乐的浪潮中,影视APP成为了人们生活中不可或缺的一部分。随着技术的不断进步,定制化的影视APP源码成为了市场上的新宠。本文将详细介绍一款名为“蝶影”的全网VIP影视APP源码,它支持五级分销模式,并提供......
  • 小鸟影视苹果cms整站源码带采集规则+支付接口+搭建教程
    小鸟影视苹果cms整站源码带采集规则+支付接口+搭建教程###小鸟影视苹果CMS整站源码带采集规则+支付接口+搭建教程在数字化时代,视频内容的需求日益增长,搭建一个功能齐全的视频网站成为了许多创业者的选择。小鸟影视苹果CMS整站源码是一个集成了采集规则和支付接口的解决方案,......
  • springboot+vue前后端分离项目-项目搭建17-集成AOP系统日志
    后端1.新增logs表和实体类,新增com/example/demo/mapper/LogsMapper.java,新增com/example/demo/controller/LogsController.javapackagecom.example.demo.controller;importcn.hutool.core.util.StrUtil;importcn.hutool.poi.excel.ExcelReader;importcn.hutool.poi......
  • 【大模型实战篇】搭建本地的隐私计算知识问答系统“密答”
    1.背景介绍           在之前分享的文章《基于开源大模型的问答系统本地部署实战教程》中,我们介绍了基于ollama实现本地问答系统的部署和使用。本文将基于ollama进一步实现本地垂直领域的问答系统搭建。ollama作为大模型的运行框架,可以提供大模型的使用接口,方便......
  • C++ //练习 16.27 对下面每条带标签的语句,解释发生了什么样的实例化(如果有的话)。如果
    C++Primer(第5版)练习16.27练习16.27对下面每条带标签的语句,解释发生了什么样的实例化(如果有的话)。如果一个模板被实例化,解释为什么;如果未实例化,解释为什么没有。template<typenameT>classStack{};voidf1(Stack<char>); //(a)classExercise{ Stack<dou......