【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.rhkb.cn/news/283259.html

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

相关文章

6个免费的ChatGPT网站

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

python的ITS 信息平台的设计与实现flask-django-nodejs-php

第二&#xff0c;陈列说明该系统实现所采用的架构、系统搭建采用的服务器、系统开发环境和使用的工具&#xff0c;以及系统后台采用的数据库。 最后&#xff0c;对系统进行全面测试&#xff0c;主要包括功能测试、查询性能测试、安全性能测试。 分析系统存在的不足以及将来改进…

haproxy 高可用

一 haproxy HAProxy简介 HAProxy提供高可用、负载均衡以及基于TCP和HTTP的应用代理&#xff0c;适合处理高负载站点的七层数据请求。类似的代理服务可以屏蔽内部真实服务器&#xff0c;防止内部服务器遭受攻击。 HAProxy特点和优点&#xff1a; 1.支持原声SSL,同时支持客户端和…

[LeetBook]【学习日记】排序算法——归并排序

主要思想 归并排序是一种分治算法&#xff0c;其排序过程包括分和治分是指将要排序的序列一分为二、二分为四&#xff0c;直到单个序列中只有一个数治是指在分完后&#xff0c;将每两个元素重新组合&#xff0c;四合为二、二合为一&#xff0c;最终完成排序 图片作者&#xf…

阿里云OSS分布式存储

目录 &#x1f9c2;1.OSS开通 &#x1f32d;2.头像上传整合OSS &#x1f68d;2.1.引入依赖 &#x1f68d;2.2添加配置 &#x1f68d;2.3创建配置类 &#x1f68d;2.4添加实现类 &#x1f68d;2.5controller调用接口 &#x1f68d;2.6postman测试 1.OSS开通 1.登…

Google XSS Game Level 6 通关方式

文章目录 链接&#xff1a;[Google XSS Game](#https://xss-game.appspot.com/)Level 6 - Follow the &#x1f407;思路1 &#xff08;当然&#xff0c;我使用这个方式没有成功&#xff0c;所以才来记录下&#xff09;解法2 【最简单的解法】需要注意的一个小问题 链接&#x…

Spring异步注解@Async线程池配置

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 从Spring3开始提供了@Async注解,该注解可以被标注在方法上,以便异步地调…

基于“云”重构“百度云盘”

这一篇文章是和上一篇连着的哟&#xff01; # docker run -p 80:80 -d -v /data/owncloud/:/var/www/html owncloud 一、【安装完成】 二、【打开浏览器】 三、【回到这个熟悉的界面&#xff0c;掉。】 四、【上传文件】 试了可以看哇偶&#xff01;&#xff01;&#xff01…

Word为图表设置图注并在图表清单中自动生成

1如果需要自动插入题注&#xff0c;请不要自己为文件增加新的标题样式或删除自带的标题1样式 2章节大标题最好是标题1&#xff0c;2,3而不要设置标题一、二、三&#xff0c;否则图例在自动生成时会显示 图一 -1&#xff0c;调整起来会非常不方便 若实在要使用大写中文标题&…

Vue模块化开发步骤—遇到的问题—解决办法

目录 1.npm install webpack -g 2.npm install -g vue/cli-init 3.初始化vue项目 4.启动vue项目 Vscode初建Vue时几个需要注意的问题-CSDN博客 1.npm install webpack -g 全局安装webpack 直接命令提示符运行改指令会报错&#xff0c;operation not permitted 注意&#…

牛客NC101 压缩字符串(一)【简单 模拟 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/c43a0d72d29941c1b65c857d8ac9047e 思路 直接模拟参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值…

Node安装,nodejs详细安装步骤

什么是nodejs? 脚本语言需要一个解析器才能运行&#xff0c;JavaScript是脚本语言&#xff0c;在不同的位置有不一样的解析器&#xff0c;如写入html的js语言&#xff0c;浏览器是它的解析器角色。而对于需要独立运行的JS&#xff0c;nodejs就是一个解析器。 每一种解析器都是…

【基于skyent的热更思考】

基于skyent的热更思考 skynet-inject热更原理关键源码分析热更方式拓扑图注意事项 skynet-inject热更原理 inject是一个用于动态加载 Lua 代码文件并执行其中定义的函数的功能。可以在运行时动态加载 Lua 代码文件&#xff0c;然后调用其中定义的函数&#xff0c;通过修改模块…

欧科云链:2024将聚焦发展与安全,用技术助力链上数据安全和合规

近期&#xff0c;OpenAI和Web3.0两大新技术发展势头迅猛。OpenAI 再次引领AI领域的新浪潮&#xff0c;推出了创新的文本转视频模型——Sora&#xff0c;Sora 可以创建长达60 秒的视频&#xff0c;包含高度详细的场景、複杂的摄像机运动以及情感丰富角色&#xff0c;再次将AI 的…

Linux-生产者与消费者模型

文章目录 一、什么是生产者与消费者模型&#xff1f;二、示例模型示例模型介绍交易场所&#xff08;blockQueue&#xff09;消费者与生产者运行结果 总结 一、什么是生产者与消费者模型&#xff1f; 参照日常生活中&#xff0c;购买商品的人群可以被称之为消费者&#xff0c;生…

mongodb文档数据建模

基础建模 内嵌方法和数组方完成关系表述 内嵌一对一关系建模 数组内嵌一对N 关系建模 数组内嵌对象多对多关系建模 文档模型设计之二&#xff1a;工况细化 join 查询 不支持外键 设计模式集锦 版本迭代加schema_version 字段 频繁写入改为时间区间写入 聚合变预聚合方式 采用…

预约陪诊APP定制开发方案以及流程详解

随着医疗行业的快速发展&#xff0c;越来越多的人开始关注自己的健康问题。然而&#xff0c;在看病的过程中&#xff0c;很多人都会感到孤独和无助。为了解决这个问题&#xff0c;许多医疗机构和企业推出了预约陪诊APP,旨在为用户提供一个安全、便捷的陪伴服务。本文将详细介绍…

爱普生EPSON全新传感技术方案亮相高交会,创造新时代“精智生活”

2023年中国国际高新技术成果交易会在深圳福田会展中心盛大举行&#xff0c;是目前中国规模最大、最具影响力的科技类展会之一。爱普生作为始终坚持“科技本地化”战略的技术创新前沿企业参与此次展会&#xff0c;为中国用户带来爱普生电子元器件三款创新技术与四大成熟传感器解…

elk收集k8s微服务日志

一、前言 使用filebeat自动发现收集k8s的pod日志&#xff0c;这里分别收集前端的nginx日志&#xff0c;还有后端的服务java日志&#xff0c;所有格式都是用json格式&#xff0c;建议还是需要让开发人员去输出java的日志为json&#xff0c;logstash分割java日志为json格式&#…

SQLiteC/C++接口详细介绍sqlite3_stmt类(十二)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十一&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十三&#xff09; 48、sqlite3_stmt_isexplain sqlite3_stmt_is…