【Flask】Flask项目结构初识

news2024/9/20 4:58:19

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 = 5999
    db.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.coloradmin.cn/o/1535676.html

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

相关文章

大数据分析-基于Python的电影票房信息数据的爬取及分析

概要 现如今&#xff0c;人民群众对物质生活水平的要求已不再局限于衣食住行&#xff0c;对于精神文化有了更多的需求。电影在我国越来越受欢迎&#xff0c;电影业的发展越来越迅猛&#xff0c;为了充分利用互联网技术的发展&#xff0c;掌握电影业的态势&#xff0c;对信息进行…

【3GPP】【核心网】【4G】4G手机接入过程,手机附着过程(超详细)

1. 4G手机接入过程&#xff0c;手机附着过程 附着&#xff08;Attach&#xff09;&#xff1a; 终端在PLMN中注册&#xff0c;从而建立自己的档案&#xff0c;即终端上下文 进行附着的三种情况&#xff1a; ①终端开机后的附着&#xff0c;初始附着 ②终端从覆盖盲区返回到…

全栈的自我修养 ———— uniapp中加密方法

直接按部就班一步一步来 一、首先创建一个js文件填入AES二、创建加密解密方法三、测试 一、首先创建一个js文件填入AES 直接复制以下内容 /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wi…

(ROOT)KAFKA详解

生产篇 使用 /** Licensed to the Apache Software Foundation (ASF) under one or more* contributor license agreements. See the NOTICE file distributed with* this work for additional information regarding copyright ownership.* The ASF licenses this file to Y…

使用Windows的“远程桌面连接”Ubuntu主机连接不上问题解决

问题描述&#xff1a; 使用Windows自带的“远程桌面连接”来连接自己的Ubuntu的系统的过程中&#xff0c;自己已经成功安装了 xrdp 文件包&#xff0c;但是在使用“远程桌面连接”时&#xff0c;自己的“远程桌面连接”软件在输入Ubuntu系统的用户名和密码后&#xff0c;连接不…

LRU的设计与实现-算法通关村

LRU的设计与实现-算法通关村 缓存是应用软件的必备功能之一&#xff0c;在操作系统&#xff0c;Java里的Spring、mybatis、redis、mysql等软件中都有自己的内部缓存模块&#xff0c;而缓存是如何实现的呢&#xff1f;在操作系统教科书里我们知道常用的有FIFO、LRU和LFU三种基本…

Java-SSM房租租赁系统

Java-SSM房租租赁系统 1.服务承诺&#xff1a; 包安装运行&#xff0c;如有需要欢迎联系&#xff08;VX:yuanchengruanjian&#xff09;。 2.项目所用框架: 前端:JSP、jquery、bootstrap等。 后端:SSM,即Spring、SpringMvc、Mybatis等。 3.项目功能点: 3-1.后端房东功能: 1.…

linux学习之Socket

目录 编写socket-udp 第一步&#xff0c;编写套接字 第二步&#xff0c;绑定端口号 第三步&#xff0c;启动服务器&#xff0c;读取数据 第四步&#xff0c;接收消息并发回信息给对方 编写socket-Tcp 第一步&#xff0c;编写套接字 第二步&#xff0c;绑定端口号 第三步…

解读BGInfo配置命令

命令行中的第一条命令是用于修改Windows注册表的&#xff0c;具体解释如下&#xff1a; reg add HKEY_CURRENT_USER\Software\Sysinternals\BGInfo /v EulaAccepted /t REG_DWORD /d 1 /f reg add&#xff1a;这是一个用来向Windows注册表添加或修改键值的命令行指令。HKEY_C…

『scrapy爬虫』10. 实战爬取自己的csdn信息(详细注释步骤)

目录 1. 数据库建表2. 搭建项目环境创建项目新建爬虫虚拟环境中安装库 定义数据类型(item.py)爬虫(spiders/csdn.py)管道(pipelines.py)中间件(middlewares.py)项目设置(setting.py)运行测试总结 欢迎关注 『scrapy爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『scrapy爬虫』 …

Git进阶用法:Git分支轻松使用,配有图文

一、文章内容 git和分支相关的概念.git和分支有关的命令.git项目实战环节. 二、相关概念 分支&#xff1a;分支的概念好比树干的分支&#xff0c;每一跟分支都是从主干分出来的&#xff0c;营养是主干给的&#xff0c;所以在git里主干和分支也是如此&#xff0c;在git里主分…

HBCalculator 程序:通过 VMD 可计算分子动力学模拟中氢键密度和强度的一维和二维分布

分享一个通过 VMD 可计算分子动力学模拟中氢键密度和强度的一维和二维分布程序 HBCalculator。 感谢论文的原作者&#xff01; 主要内容 “氢键是分子系统中关键的非共价相互作用&#xff0c;对生物、化学和能量相关过程产生重大影响&#xff1b;因此&#xff0c;描述氢键信息…

Leetcode 70.爬楼梯

心路历程&#xff1a; 这道题是之前学院的一道复试题&#xff0c;大家都没怎么刷过算法题&#xff0c;只记得当年凭借几次试错自己把这道题做出来了&#xff0c;当时也不知道动态规划之类的。 正常来讲&#xff0c;这种找不到循环结构的题一般都是递归解决。 注意的点&#x…

Day02-DDLDMLDQL(定义,操作,查询)(联合查询,子查询,字符集和校对集,MySQL5.7乱码问题)

文章目录 Day02-DDL&DML和DQL学习目标1. SQL语言的组成2. DDL2.1 数据库结构2.2 表结构2.3 约束2.3.1 主键约束(重要)(1)特点(2) 添加主键(3)删除主键(了解) 2.3.2 自增约束(1)特点(2) 添加自增约束(3)删除自增约束(了解) 2.3.3 非空约束(1)添加非空约束(2) 删除非空约束 2…

EtherCAT 开源主站 IGH 在 linux 开发板的移植和伺服通信测试

手边有一套正点原子linux开发板imax6ul&#xff0c;一直在吃灰&#xff0c;周末业余时间无聊&#xff0c;把EtherCAT的开源IGH主站移植到开发板上玩玩儿&#xff0c;搞点事情做。顺便学习研究下EtherCAT总线协议及其对伺服驱动器的运动控制过程。实验很有意思&#xff0c;这里总…

森林防火广播应急广播系统方案

森林防火广播应急广播系统方案 深圳锐科达网络应急广播方案 森林防火广播建设必要性&#xff1b; 森林火灾是一种突发性和破坏性极强的自然灾害&#xff0c;它的后果不仅直接危害森林资源和人民生命财产安全&#xff0c;而且会影响到气候、植被及环境等多个因素的变化&#…

git tag标签使用

创建标签 git checkout test git tag -a v1.0.0 -m v1.0.0里程碑版本 git push origin v1.0.0 删除标签 git tag -d v1.0.0 git push origin :refs/tags/v1.0.0远程分支可以直接在页面删除

day15-maven高级

1. 分模块设计与开发 步骤 创建 maven 模块 tlias-pojo&#xff0c;存放实体类。创建 maven 模块 tlias-utils&#xff0c;存放相关工具类。 <dependency><groupId>com.itheima</groupId><artifactId>tlias-pojo</artifactId><version>1.0…

气液分离器的概念和原理

气液分离器也叫低压储液器&#xff0c;在热泵或制冷系统中使用&#xff0c;主要是将出蒸发器、进压缩机气流中的液滴分离出来&#xff0c;防止压缩机发生液击&#xff0c;用于工质充注量较大、压缩机进气可能带液且压缩机对湿压缩较敏感的情况 。 液击主要出现在活塞式压缩机中…

【探讨】基于卷积神经网络深度学习模型的光场显微三维粒子空间分布重建

光场显微粒子图像测速技术通过单光场相机即可实现微尺度三维速度场的测量&#xff0c;但单光场相机角度信息有限&#xff0c;导致粒子重建的轴向分辨率低、重建速度慢。基于此&#xff0c;提出一种基于卷积神经网络深度学习模型的光场显微粒子三维空间分布重建方法&#xff0c;…