Python的Flask框架的学习笔记(前后端变量传送,文件上传,网页返回)内含实战:实现一个简单的登录页面

写在前面

Flask是一个使用 Python 编写的轻量级 Web 应用框架。Flask对比Django框架灵活度更高了,可以自己一些设计代码框架,可以说他是短小精悍。

学习flask框架的目的是给自己的网页做一个后台系统、搭建属于自己的api系统,这也是我学习这款框架的原因。

下面我们开始正题

配置环境

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Flask

创建项目文件

这里我是用的开发软件是Visual Studio Code
首先在在存放项目的位置新建这样几个文件
在这里插入图片描述
目录结构为

pyflask
--app
----templates
------index.html
----__init__.py
----routes.py
--run.py

然后右击项目文件夹pyflask使用vscode打开

这里我就犯过这种错误,如果不以文件夹的方式打开项目最终程序会因为找不到路径报错

Hello Flask

然后我们分别给每个文件填上以下代码

init.py

# 这里注意导包的顺序不能错乱
from flask import Flask
# 创建app应用,__name__是python预定义变量,被设置为使用本模块.
app = Flask(__name__)
from app import routes

routes.py

# 从app模块中即从__init__.py中导入创建的app应用
from app import app


@app.route('/')
def getIndex():
    return 'Hello Flask!'

run.py : 这里我们需要了解的地方是app.run()这个函数
debug参数开启后文件发生改变及时重启服务器
关闭后需要手动重启服务器内容才会发生改变
host为ip地址默认为以下参数,然后我们通过127.0.0.1即可访问
port参数为访问端口

# 从app模块中导入app应用
from app import app

# 防止被引用后执行,只有在当前模块中才可以使用
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=3000)

index.html(这里我们还用不到,但是后面的返回网页需要使用)

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
        <title>这个是我的标题</title>
    </head>
<body>
   这里是我的网页内容
</body>
</html>

然后我们运行run.py出现以下信息表明运行成功这个使用我们访问
win:http://127.0.0.1:3000/ 或者 http://localhost:3000/
linux:http://localhost:3000/
在这里插入图片描述然后我们就会看到以下结果在这里插入图片描述恭喜你已经完整搭建好了flask框架!

通过代码我们可以看到我们前台的数据和routes.py文件中的函数返回的内容相同,是的我们的内容确实是来源于routes.py也就是路由,读者可以自行尝试更改return的内容来测试前台数据的变化。

下面我们使用flask框架返回一个网页试试

请求方式GET与POST

在这里插入图片描述在信息输出创口我们可以看到我们通过浏览器访问数据是使用的get请求,如果我们要实现post访问的测试我们需要用到一个软件
apipost
然后我们使用get请求再试一下前面的测试
在这里插入图片描述返回没有问题,然后我们使用post请求测试以下
在这里插入图片描述我们可以看到网页返回了一个405错误
然后我们这里引入新的知识,访问方式在routes.py中修改内容为

# 从app模块中即从__init__.py中导入创建的app应用
from app import app

@app.route("/", methods=["GET", "POST"])
def getIndex():
    return 'Hello Flask!'

这里我们给app.route()中添加了一个methods参数这个参数表示该路由接口可以使用GET和POST两种方式请求,下面我们实现一个post和get请求分别返回不同内容的例子
在routes.py中修改

from app import app
from flask import request       # 判断get还是post请求

@app.route("/", methods=("GET", "POST"))
def getIndex():
    if request.method == "POST":
        return "post flask"
    else:
        return 'Hello Flask!'

然后我们再使用工具测试一下

在这里插入图片描述在这里插入图片描述
下面我们开始实现返回一个网页试试

返回一个网页

这里我们就要用到前面创建的templates文件夹了(其实主要还是要用文件夹下面的html文件)
然后我们在routes文件中新建一个路由,并引用返回html的模块,具体内容如下:

from app import app
from flask import request       # 判断get还是post请求
from flask import render_template  # 读取template中的网页文件


@app.route("/", methods=("GET", "POST"))
def getIndex():
    if request.method == "POST":
        return "post flask"
    else:
        return 'Hello Flask!'


@app.route("/index")
def getHtml():
    return render_template('index.html')

然后我们通过浏览器访问可以得到以下内容
在这里插入图片描述

发送数据到前台

然后我们来实现通过后台修改前台数据内容,这里展示两种方式实现:
方式一:

routes.py

@app.route("/index/<title>")
def getHtml(title):
    return render_template('index.html', title=title)

index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
        <title>{{title}}</title>
    </head>
<body>
   这里是我的网页内容
</body>
</html>

效果
在这里插入图片描述

方式二:

@app.route("/test")
def getTest():
    title = "情人节快乐"
    return render_template('index.html', title=title)

沿用方式一的index页面内容即可
在这里插入图片描述
再index文件中其实我们也可以使用判断语句以及for语句,具体使用方法如下

{% if text %}
  <h1>传入得内容为{{ text}}!</h1>
{% else %}
  <h1>未传入内容</h1>
{% endif %}

在html中使用{{ 变量 }}来接受后台传入的数据
使用{% 语句 %}来循环和判断语句
在这里插入图片描述这里我的代码为
routes.py

from app import app
from flask import request       # 判断get还是post请求
from flask import render_template  # 读取template中的网页文件


@app.route("/", methods=("GET", "POST"))
def getIndex():
    if request.method == "POST":
        return "post flask"
    else:
        return 'Hello Flask!'


@app.route("/index/<title>")
def getHtml(title):
    return render_template('index.html', title=title)

    
@app.route("/test/")
@app.route("/test/<text>")
def getTest(text=None):
    title = "情人节快乐"
    return render_template('index.html', title=title, text=text)

index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
        <title>{{title}}</title>
    </head>
<body>
    {% if text %}
        <h1>传入得内容为{{ text }}!</h1>
    {% else %}
        <h1>未传入内容</h1>
    {% endif %}

</body>
</html>

获取前台数据

这里我们就会用到post请求方式,get又称为显示请求,post称为隐示请求,如果我们写一个网站把账号密码显示到浏览地址是不是总觉得不安全吧,所以我们这里需要使用到post请求,但是post请求也不是绝对安全,但是我们在数据传输得过程中肯定是要使用post请求得,这样必get肯定安全不少,下面看示例:
这里我们在templates文件夹下面添加一个login.html文件内容如下:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
        <title>登录页面</title>
    </head>
<body>

    <form align="center" action="#" method="post">
        username:<input type="text" name="username"/> </br>
        password:<input type="password" name="password"/></br>
        <button type="submit">登录</button></br>
        {{ msg }}
    </form>

</body>
</html>

然后再路由文件夹下面添加

@app.route("/login", methods=['GET', 'POST'])
def login():
	#方式1
	# user_info = request.form.to_dict()
    # if user_info.get("username") == "admin" and user_info.get("password") == '123456':
    #   return redirect("/")
    #方式2
    username = request.form.get("username")
    password = request.form.get("password")
    if username == "admin" and password == "123456":
        return render_template("index.html", title="登录成功")
    elif request.method == 'GET':
        return render_template("login.html")
    else:
        return render_template("login.html", msg="账号密码错误")

然后我们测试账号密码登录:账号密码错误提示
在这里插入图片描述账号密码正确提示
在这里插入图片描述
这里我们要获取前端传给我们得数据就需要使用到request.form.get(“变量名”)函数
前端传给后端数据需要使用到提交按钮以及数据块

上传文件到后端

新建一个file页面内容为:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <title>文件上传</title>
</head>

<body>
    <form align = "center" action="#" method="post" enctype="multipart/form-data">
        文件:<input type="file" name="files">
        <button type="submit">上传</button>
    </form>
</body>
</html>

新建一个路由内容为:

@app.route("/file", methods=("GET", "POST"))
def updateFile():
    if request.method == "POST":
        # 获取上传文件数据
        file = request.files.get('files')
        # 保存文件到根目录
        file.save(file.filename)
        return render_template("file.html")
    else:
        return render_template("file.html")

实现效果
在这里插入图片描述在这里插入图片描述到这里我们就实现了Flask框架的前后端变量传送,文件上传,网页返回内容,更多得知识需要阅读开发手册进行查看!下面我们来通过已学得知识来做一个简单的登录页面

实战:实现一个简单的登录页面

init.py

# 这里注意导包的顺序不能错乱
from flask import Flask
# 创建app应用,__name__是python预定义变量,被设置为使用本模块.
app = Flask(__name__)
from app import routes

templates文件中得index文件
Index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="utf-8">
<title>巴拉巴拉巴拉~~~~我也不知道取什么</title>
<link rel="stylesheet" href="static/css/style.css">
</head>

<body>
    <div class="content">
        <div class="form sign-in">
            <h2>欢迎回来</h2>
            
            <form action="#" method="post">
                <label>
                    <span>用户名</span>
                    <input type="text" name="username" />
                </label>
                <label>
                    <span>密码</span>
                    <input type="password" name="userpwd" />
                </label>
                <!-- <p class="forgot-pass"><a href="javascript:">忘记密码?</a></p> -->
                <button type="submit" class="submit">登 录</button>
                <label><span>{{msg}}</span></label>
            </form>

        </div>
        <div class="sub-cont">
            <div class="img">
                <div class="img__text m--up">
                    <h2>还未注册?</h2>
                    <p>立即注册,发现大量机会!</p>
                </div>
                <div class="img__text m--in">
                    <h2>已有帐号?</h2>
                    <p>有帐号就登录吧,好久不见了!</p>
                </div>
                <div class="img__btn">
                    <span class="m--up">注 册</span>
                    <span class="m--in">登 录</span>
                </div>
            </div>
            <div class="form sign-up">
                <h2>立即注册</h2>
                <form action="#" method="post">
                    <label>
                        <span>用户名</span>
                        <input type="text" name="name" />
                    </label>
                    <!-- <label>
                        <span>邮箱</span>
                        <input type="email" />
                    </label> -->
                    <label>
                        <span>密码</span>
                        <input type="password" name="pwd" />
                    </label>
                    <button type="submit" class="submit">注 册</button>
                </form>
            </div>
        </div>
    </div>

    <script src="static/js/script.js"></script>
	
</body>

</html>

然后我们再在工程文件中新建一个static文件夹用来存放网页得静态文件(js,css,img)
目录结构:
static
js
script.js
css
stylle.css
images
bg.jpg
stylle.css

*,
*:before,
*:after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Open Sans", Helvetica, Arial, sans-serif;
  background: #ededed;
}

input,
button {
  border: none;
  outline: none;
  background: none;
  font-family: "Open Sans", Helvetica, Arial, sans-serif;
}

.tip {
  font-size: 20px;
  margin: 40px auto 50px;
  text-align: center;
}

.content {
  overflow: hidden;
  position: absolute;
  left: 50%;
  top: 50%;
  width: 900px;
  height: 550px;
  margin: -300px 0 0 -450px;
  background: #fff;
}

.form {
  position: relative;
  width: 640px;
  height: 100%;
  transition: -webkit-transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
  padding: 100px 30px 0;
}

.sub-cont {
  overflow: hidden;
  position: absolute;
  left: 640px;
  top: 0;
  width: 900px;
  height: 100%;
  padding-left: 260px;
  background: #fff;
  transition: -webkit-transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
}

.content.s--signup .sub-cont {
  -webkit-transform: translate3d(-640px, 0, 0);
  transform: translate3d(-640px, 0, 0);
}

button {
  display: block;
  margin: 0 auto;
  width: 260px;
  height: 36px;
  border-radius: 30px;
  color: #fff;
  font-size: 15px;
  cursor: pointer;
}

.img {
  overflow: hidden;
  z-index: 2;
  position: absolute;
  left: 0;
  top: 0;
  width: 260px;
  height: 100%;
  padding-top: 360px;
}

.img:before {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  width: 900px;
  height: 100%;
  background-image: url(../images/bg.jpg);
  background-size: cover;
  transition: -webkit-transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
}

.img:after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.6);
}

.content.s--signup .img:before {
  -webkit-transform: translate3d(640px, 0, 0);
  transform: translate3d(640px, 0, 0);
}

.img__text {
  z-index: 2;
  position: absolute;
  left: 0;
  top: 50px;
  width: 100%;
  padding: 0 20px;
  text-align: center;
  color: #fff;
  transition: -webkit-transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out;
  transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
}

.img__text h2 {
  margin-bottom: 10px;
  font-weight: normal;
}

.img__text p {
  font-size: 14px;
  line-height: 1.5;
}

.content.s--signup .img__text.m--up {
  -webkit-transform: translateX(520px);
  transform: translateX(520px);
}
.img__text.m--in {
  -webkit-transform: translateX(-520px);
  transform: translateX(-520px);
}

.content.s--signup .img__text.m--in {
  -webkit-transform: translateX(0);
  transform: translateX(0);
}

.img__btn {
  overflow: hidden;
  z-index: 2;
  position: relative;
  width: 100px;
  height: 36px;
  margin: 0 auto;
  background: transparent;
  color: #fff;
  text-transform: uppercase;
  font-size: 15px;
  cursor: pointer;
}
.img__btn:after {
  content: "";
  z-index: 2;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  border: 2px solid #fff;
  border-radius: 30px;
}

.img__btn span {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  transition: -webkit-transform 0.6s;
  transition: transform 0.6s;
  transition: transform 0.6s, -webkit-transform 0.6s;
}

.img__btn span.m--in {
  -webkit-transform: translateY(-72px);
  transform: translateY(-72px);
}

.content.s--signup .img__btn span.m--in {
  -webkit-transform: translateY(0);
  transform: translateY(0);
}

.content.s--signup .img__btn span.m--up {
  -webkit-transform: translateY(72px);
  transform: translateY(72px);
}

h2 {
  width: 100%;
  font-size: 26px;
  text-align: center;
}

label {
  display: block;
  width: 260px;
  margin: 25px auto 0;
  text-align: center;
}

label span {
  font-size: 12px;
  color: #909399;
  text-transform: uppercase;
}

input {
  display: block;
  width: 100%;
  margin-top: 5px;
  padding-bottom: 5px;
  font-size: 16px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.4);
  text-align: center;
}

.forgot-pass {
  margin-top: 15px;
  text-align: center;
  font-size: 12px;
  color: #cfcfcf;
}

.forgot-pass a {
  color: #cfcfcf;
}

.submit {
  margin-top: 40px;
  margin-bottom: 20px;
  background: #d4af7a;
  text-transform: uppercase;
}

.fb-btn {
  border: 2px solid #d3dae9;
  color: #8fa1c7;
}
.fb-btn span {
  font-weight: bold;
  color: #455a81;
}

.sign-in {
  transition-timing-function: ease-out;
}
.content.s--signup .sign-in {
  transition-timing-function: ease-in-out;
  transition-duration: 0.3s;
  -webkit-transform: translate3d(640px, 0, 0);
  transform: translate3d(640px, 0, 0);
}

.sign-up {
  -webkit-transform: translate3d(-900px, 0, 0);
  transform: translate3d(-900px, 0, 0);
}
.content.s--signup .sign-up {
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}

script.js

document.querySelector('.img__btn').addEventListener('click', function() {
    document.querySelector('.content').classList.toggle('s--signup')
})

bg.jpg
在这里插入图片描述routes.py

# 从app模块中即从__init__.py中导入创建的app应用
from app import app
from flask import render_template
from flask import request
# 建立路由,通过路由可以执行其覆盖的方法,可以多个路由指向同一个方法。


@app.route('/', methods=['POST', 'GET'])
@app.route('/index', methods=['POST', 'GET'])
def index():
    username = request.form.get("username")
    userpwd = request.form.get("userpwd")
    if username == "stylle" and userpwd == "daikongjun":
        return render_template("user.html")
    elif request.method == 'GET':
        return render_template("index.html")
    else:
        return render_template("index.html", msg="登录失败")


@app.route('/user')
def getUser():
    return render_template("user.html")

run.py

# 从app模块中导入app应用
from app import app

# 防止被引用后执行,只有在当前模块中才可以使用
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

然后我们部署到服务器通过公网ip访问效果
在这里插入图片描述

  • 7
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
好的,下面是一个简单前后端分离的项目示例,使用 Python Flask 框架和 Vue.js 前端框架。 1. 环境配置 首先,需要安装 Python 3 和 Node.js。 然后,使用以下命令安装 Flask 和相关扩展: ``` pip install flask flask-cors flask-restful ``` 2. 后端开发 在项目根目录下创建 `app.py` 文件,编写以下代码: ```python from flask import Flask, jsonify from flask_cors import CORS from flask_restful import Api, Resource app = Flask(__name__) api = Api(app) CORS(app) class HelloWorld(Resource): def get(self): return jsonify({"message": "Hello, World!"}) api.add_resource(HelloWorld, "/api/hello") if __name__ == "__main__": app.run(debug=True) ``` 这个代码创建了一个 Flask 应用,同时使用 Flask-RESTful 扩展创建了一个 `/api/hello` 的 API,返回一个 JSON 格式的消息。 3. 前端开发 在项目根目录下,使用以下命令初始化一个 Vue.js 项目: ``` vue create frontend ``` 然后,进入 `frontend` 目录,使用以下命令安装 axios: ``` npm install axios --save ``` 接着,创建一个 `src/App.vue` 文件,编写以下代码: ```html <template> <div> <h1>{{ message }}</h1> </div> </template> <script> import axios from "axios"; export default { data() { return { message: "", }; }, mounted() { axios.get("http://localhost:5000/api/hello").then((res) => { this.message = res.data.message; }); }, }; </script> ``` 这个代码创建了一个 Vue.js 应用,通过 axios 发送 HTTP 请求到 Flask 后端,获取 `/api/hello` 的响应,并显示在页面上。 4. 运行项目 在项目根目录下,使用以下命令分别启动 Flask 和 Vue.js 服务器: ``` python app.py ``` ``` cd frontend npm run serve ``` 然后,打开浏览器,访问 `http://localhost:8080`,即可看到页面上显示的消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉开水白菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值