【Flask】Flask项目结构初识

1.前提准备

  • Python版本

    # python 3.8.0
    # 查看Python版本
    python --version
  • 安装第三方 Flask

    pip install flask
    # 如果安装失败,可以使用 -i,指定使用国内镜像源
    # 清华镜像源:https://pypi.tuna.tsinghua.edu.cn/simple/

  • 检查 Flask 是否安装成功

    flask --version
  • Flask官网

    # 官网:https://flask.palletsprojects.com
    # 快速开始:https://flask.palletsprojects.com/en/3.0.x/quickstart/

2.一个简单的Flask程序

  1. 创建 Flask 项目目录。

    mkdir FlaskMarket

  2. 创建 app 文件。

    from flask import Flask
    ​
    app = Flask(__name__)
    ​
    @app.route("/")
    def hello_world():return "<p>Hello, World!</p>"

  3. 运行 Flask

    flask --app market run
    # 设置环境变量,也能够直接运行flask
    $env:FLASK_APP="market.py"
    flask run

    查看web页面

    Debug 模式

    # 运行flask项目时,在最后加--debug,以debug模式启动
    $env:FLASK_APP="market.py"
    flask run --debug

    以下是代码产生报错的截图

  4. 新增一个路由。

    # 路由传参username
    @app.route("/about/<username>")
    def about_page(username):return f"<h1>this is about {username} page</h1>"

    页面查询结果

3.Template模板文件

可以在Flask项目的目录下创建 templates 目录存放所会用的 html 文件,具体如下:

在Python代码中,直接返回 html 文件即可,不需要携带目录。

@app.route("/")
def hello_world():return render_template("hello.html")

页面访问如下

4.数据发送到template

Jinjia2 是一个仿照 Django 模板的 Python 模板语句,实现了后端与模板之间的交互。

  1. 一个简单的数据交互。

    后端 python 这样写:

    @app.route("/")
    def hello_world():return render_template("home.html", item_name="Phone")

    对应的前端 html 文件需要使用 jiajia2 的语法接收变量,代码如下:

    <p>{{item_name}}</p>

    页面效果如下:

  1. 列表数据交互。

    后端 python 这样写:

    @app.route("/")
    def hello_world():items = [{"id": 1, "name": "Phone", "barcode": 123456789, "price": 500},{"id": 2, "name": "Laptop", "barcode": 123654789, "price": 500},{"id": 3, "name": "keybord", "barcode": 123456987, "price": 150},]return render_template("home.html", items=items)

    对应的前端 html 这样接收:

    <table class="table table-hover table-dark"><thead><tr><th scope="col">ID</th><th scope="col">Name</th><th scope="col">Barcode</th><th scope="col">Price</th></tr></thead><tbody>{% for item in items %}<tr><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.barcode}}</td><td>{{item.price}}</td></tr>{% endfor %}</tbody>
    </table>

    访问页面如下:

5.Template 继承

开发的网站可能涉及多个页面,需要抽取公共的内容,其余的 html 页面继承这些公共内容即可。

  1. 引入 base.html 文件。

    <!doctype html>
    <html lang="en"><head><!-- Required meta tags --><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><!-- Bootstrap CSS --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"><title>Base Title</title></head><body><!-- Navbar here --><nav class="navbar navbar-expand-md navbar-dark bg-dark"><a class="navbar-brand" href="#">EuanSu Coding Market</a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="*navbarNav"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarNav"><ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="#">Market</a></li></ul><ul class="navbar-nav"><li class="nav-item"><a class="nav-link" href="#">Login</a></li><li class="nav-item"><a class="nav-link" href="#">Register</a></li></ul></div>
    ​</nav><!-- Future Content here -->
    ​
    ​
    ​
    ​<!-- Optional JavaScript --><!-- jQuery first, then Popper.js, then Bootstrap JS --><script src='https://kit.fontawesome.com/a076d05399.js'></script><script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script></body><style>body {background-color: #212121;color: white}</style>
    </html>

  2. 清空 home.html 原文件,修改为如下内容:

    {% extends "base.html" %}

  3. 访问页面如下:

    这里有一个问题就是页面标题显示为 Base Title ,实际上每个页面的标题是不一样,这里可以通过 block 语句进行修改,代码如下:

    修改 base.html 文件 head 下的 title 标签为如下内容:

    <head>...<title>{% block title%}{% endblock %}</title>
    </head>

    修改 home.html 为如下内容:

    {% extends "base.html" %}
    {% block title%}
    Home Page
    {% endblock %}

    再次刷新页面,title 的内容被替换。

  4. 替换 html 文件 body 下的内容:

    首先是修改 base.htmlbody 的内容,修改如下:

    {% block content%}
    {% endblock %}

    修改 market.html 为如下内容:

    {% extends "base.html" %}
    {% block title%}
    Market Page
    {% endblock %}
    {% block content%}
    <table class="table table-hover table-dark"><thead><tr><th scope="col">ID</th><th scope="col">Name</th><th scope="col">Barcode</th><th scope="col">Price</th></tr></thead><tbody>{% for item in items %}<tr><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.barcode}}</td><td>{{item.price}}</td><td><button class="btn btn-outline btn-info">More Info</button><button class="btn btn-outline btn-success">Purchase this Item</button></td></tr>{% endfor %}</tbody></table>
    {% endblock %}

    访问页面,能够正常对数据进行渲染。

  1. 页面跳转

    html 文件的 href 进行跳转,这里需要使用 jinjia2 的语法,而不能直接使用路由。

    <a class="nav-link" href="{{ url_for('home_page') }}">Home <span class="sr-only">(current)</span></a>
    <a class="nav-link" href="{{ url_for('market_page') }}">Market</a>

    其中的 market_page 是路由关联的函数,如下所示:

    @app.route("/")
    def home_page():items = [{"id": 1, "name": "Phone", "barcode": 123456789, "price": 500},{"id": 2, "name": "Laptop", "barcode": 123654789, "price": 500},{"id": 3, "name": "keybord", "barcode": 123456987, "price": 150},]return render_template("home.html", items=items)
    ​
    ​
    @app.route("/market")
    def market_page():items = [{"id": 1, "name": "Phone", "barcode": 123456789, "price": 500},{"id": 2, "name": "Laptop", "barcode": 123654789, "price": 500},{"id": 3, "name": "keybord", "barcode": 123456987, "price": 150},]return render_template("market.html", items=items)

    再次点击页面的按钮,能够正常进行路由跳转。

6.数据库模型

6.1 数据库模型的基本使用

安装 flask-sqlalchemy 第三方包。

pip install flask-sqlalchemy

python 文件导入 flask-sqlalchemy 库。

from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///market.sqlite'
db = SQLAlchemy(app)

编写模型类。

class Item(db.Model):id = db.Column(db.Integer(), primary_key=True)name = db.Column(db.String(length=30),nullable=False, unique=True)price = db.Column(db.Integer(), nullable=True)barcode = db.Column(db.String(length=12), nullable=True, unique=True)description = db.Column(db.String(length=1024), nullable=True, unique=True)

需要在 Flaskapp 文件中,添加数据库初始化操作。

with app.app_context():db.create_all()

使用可视化工具查看 SQLite 本地数据库文件,出现初始化的 Item 表。

6.2 SQLAlchemy 的基本使用

新增数据库记录

item1 =  Item(name="OPPO Find X6 Pro",price=5000,barcode='123456789',description='OPPO Find X6 Pro')
with app.app_context():db.session.add(item1)db.session.commit()

执行如上语句后,数据库中出现一条手机记录。

查询数据库记录

# 全量查询
result = Item.query.all()
print(result)
for item in result:print(item.name)

# 根据条件过滤
result = Item.query.filter_by(name='OPPO Find X6 Pro')
print(result)
print('=============')
for item in result:print(item.name)

修改数据库记录

result = Item.query.filter_by(name='OPPO Find X6 Pro')
if result:item = result[0]item.price = 5999db.session.commit()

修改后,数据库中的记录发生了变化。

删除数据库记录

# 查询要删除的记录
record_to_delete = Item.query.filter_by(name="OnePlus 12").first()
# 如果记录存在,则删除
if record_to_delete:db.session.delete(record_to_delete)db.session.commit()

这里的数据库查询放到代码中,如下:

@app.route("/market")
def market_page():items = [{"id": 1, "name": "Phone", "barcode": 123456789, "price": 500},{"id": 2, "name": "Laptop", "barcode": 123654789, "price": 500},{"id": 3, "name": "keybord", "barcode": 123456987, "price": 150},]items = Item.query.all()return render_template("market.html", items=items)

页面就能够直接展示数据库中的记录

7.项目重构

# 这里将项目移动至mark目录下,主目录下仅留项目的启动文件 run.py
D:\CODE\PYTHON\FLASKMARKET
├─instance
├─market
│  ├─templates
│  │  ├─css
│  │  ├─js
│  │  ├─base.html
│  │  ├─home.html
│  │  └─market.html
│  ├─__init__.py
│  ├─models.py
│  ├─routes.py
│  └─__pycache__
├─run.py
└─__pycache__

修改后的各文件一次如下所示:

__init__.py 模块初始化文件:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
​
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///market.sqlite'
db = SQLAlchemy(app)
​
from market import routes

models.py 模型文件:

from market import db
class Item(db.Model):id = db.Column(db.Integer(), primary_key=True)name = db.Column(db.String(length=30),nullable=False, unique=True)price = db.Column(db.Integer(), nullable=True)barcode = db.Column(db.String(length=12), nullable=True, unique=True)description = db.Column(db.String(length=1024), nullable=True, unique=True)

routes.py 路由文件:

from market import app
from flask import render_template
from market.models import Item
@app.route("/")
@app.route("/home")
def home_page():items = [{"id": 1, "name": "Phone", "barcode": 123456789, "price": 500},{"id": 2, "name": "Laptop", "barcode": 123654789, "price": 500},{"id": 3, "name": "keybord", "barcode": 123456987, "price": 150},]return render_template("home.html", items=items)
​
​
@app.route("/market")
def market_page():items = [{"id": 1, "name": "Phone", "barcode": 123456789, "price": 500},{"id": 2, "name": "Laptop", "barcode": 123654789, "price": 500},{"id": 3, "name": "keybord", "barcode": 123456987, "price": 150},]items = Item.query.all()return render_template("market.html", items=items)

再次启动项目:

页面能够正常访问

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

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

相关文章

SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述…

Qt如何直接处理系统事件(比如鼠标事件),而不是post事件

#include <QtGui/5.15.2/QtGui/qpa/qwindowsysteminterface.h> // 方便调试事件 QWindowSystemInterface::setSynchronousWindowSystemEvents(true); 直接再 qWindowsWndProc函数中处理 通常情况: 事件被放到一个队列中

基于springboot+vue+Mysql的垃圾分类网站

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

JavaScript高级(十)----JavaScript中的类【重述原型链】!

类 在JavaScript其实本来没有类的概念&#xff0c;哪怕是ES5以后的class&#xff0c;严格意义上来说也只是构造函数的语法糖&#xff0c;之所以喜欢称之为类&#xff0c;因为JavaScript也可以面向对象开发。 类的声明 class Person {}function Person1() {}// 上面两种写法本…

Milvus 向量数据库介绍及使用

一、Milvus 介绍及安装 Milvus 于 2019 年创建&#xff0c;其目标只有一个&#xff1a;存储、索引和管理由深度神经网络和其他机器学习 (ML) 模型生成的大量嵌入向量。它具备高可用、高性能、易拓展的特点&#xff0c;用于海量向量数据的实时召回。 作为专门为处理输入向量查…

Linux:权限的概念与理解

目录 1. Linux权限的概念 2. Linux权限管理 01.文件访问者的分类 02.文件类型和访问权限 03.文件权限值的表示方法 04. 文件访问权限的相关设置方法 3. 使用 sudo分配权限 4. 目录的权限 ---------- 权限 用户角色(具体的人) 文件权限属性 ---------- 1. Linux权限的…

代码随想录--排序算法

912.排序数组 快速排序 思路&#xff1a; 1. 设置一个pivot2. 将小于nums[pivot]的值 放在左边3. 将 大于nums[pivot]的值 放在 右边4. 递归调用注意&#xff1a;必须先比较nums[high] 与pivot 代码&#xff1a; class Solution {int partition(vector<int>&nu…

无人机采集图像的相关知识

1.飞行任务规划 一般使用飞行任务规划软件进行飞行任务的设计&#xff0c;软件可以自动计算相机覆盖和图像重叠情况。比如ArduPilot (ArduPilot - Versatile, Trusted, Open) 和UgCS (http://www.ugcs.com)是两个飞行任务规划软件&#xff0c;可以适用大多数无人机系统。 2.图…

QT作业。。

1.使用手动连接&#xff0c;将登录框中的取消按钮使用t4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数将登录按钮使用t5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断u界面上输入的账号是否为"admin"&#xff0c;密码是否为&q…

【计算机视觉】Gaussian Splatting源码解读补充(一)

本文旨在补充gwpscut创作的博文学习笔记之——3D Gaussian Splatting源码解读。 Gaussian Splatting Github地址&#xff1a;https://github.com/graphdeco-inria/gaussian-splatting 论文地址&#xff1a;https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gauss…

mac 用electron-builder打包,如何切换到notarytool

背景&#xff1a;altool已经被遗弃了&#xff0c;我们必须要使用notarytool进行打包,如何从altool切换到notarytool 在打包的配置中afterSign执行的js中 加入teamId和tool teamId在你的开发者账号中可以获取到

二、SpringBoot3 配置文件

本章概要 统一配置管理概述属性配置文件使用YAML 配置文件使用批量配置文件注入多环境配置和使用 2.1 统一配置管理概述 SpringBoot工程下&#xff0c;进行统一的配置管理&#xff0c;你想设置的任何参数&#xff08;端口号、项目根路径、数据库连接信息等等)都集中到一个固定…

docker镜像复制与常见命令

一、前言 最近通过阿里的镜像仓库远程拉取镜像&#xff0c;发现以前的版本不见了&#xff0c;拉取了最新的镜像&#xff0c;有发现版本不配问题。那么想使用老版本的镜像那就要从别的环境获取。于是就需要进行离线镜像复制&#xff0c;打包&#xff0c;上传&#xff0c;重新导入…

6个免费的ChatGPT网站

AI 大模型的出现给时代带来了深远的影响&#xff1a; 改变了产业格局&#xff1a;AI 大模型的发展推动了人工智能技术在各行业的广泛应用&#xff0c;改变了传统产业的运作方式&#xff0c;促进了新兴产业的崛起&#xff0c;如智能驾驶、医疗健康、金融科技等。提升了科学研究…

MNN 执行推理(九)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session 之维度计算&#xff08;五…

两台电脑简单的通信过程详解(经过两个路由器,不同网段)

一、eNSP拓扑图 二、配置4台电脑的IP地址、子网掩码、网关地址。 三、配置路由器 注意拓扑图的接口与本博客是否相符&#xff0c;判断以下命令中的ip是否需要修改。 1.AR1-接口对应IP <Huawei>sys #进入系统视图 [Huawei]int g0/0/0 #进入0/0/0接口 [Huawei-GigabitE…

【计算机网络篇】数据链路层(1)数据链路层的地位,问题

文章目录 &#x1f354;数据链路层在网络体系结构中的地位&#x1f354;链路&#xff0c;数据链路&#xff0c;帧&#x1f354;数据链路层的三个重要问题&#x1f95a;封装成帧和透明传输&#x1f95a;差错检测&#x1f95a;可靠传输 &#x1f354;数据链路层在网络体系结构中的…

飞天使-k8s知识点26-kubernetes温故知新1-pod

文章目录 创建一个podpod的启动命令和参数更改pod 镜像拉取策略 pod 的三种探针pod 探针的实现方式prestop 和 prestart 创建一个pod apiVersion: v1 # 必选&#xff0c;API 的版本号 kind: Pod # 必选&#xff0c;类型 Pod metadata: # 必选&#xff0c;元数据name: nginx # …

Linux文件 profile、bashrc、bash_profile区别

Linux系统中&#xff0c;有三种文件 出现的非常频繁&#xff0c;那就是 profile、bash_profile、bashrc 文件。 1、profile 作用 profile&#xff0c;路径&#xff1a;/etc/profile&#xff0c;用于设置系统级的环境变量和启动程序&#xff0c;在这个文件下配置会对所有用户…

欣瑞达信息技术邀您莅临2024长三角快递物流展

2024数字物流技术展 2024新能源商用车及物流车展 2024电商物流包装展 2024冷链物流展 2024年7月8-10日 | 杭州国际博览中心 参展企业介绍 深圳市欣瑞达信息技术有限公司&#xff08;曾用名&#xff1a;深圳市欣瑞达液晶显示技术有限公司&#xff09;成立于1997年&#xff0c;是…