Web 框架 Flask 快速入门(二)表单

news2024/9/27 23:27:34

课程地址:Python Web 框架 Flask 快速入门

文章目录

  • 🌴 表单
    • 1、表单介绍
    • 2、表单的简单实现
      • 1. 代码
      • 2. 代码的执行逻辑
    • 3、使用wtf扩展实现
    • 4、bug记录:表单验证总是失败


🌴 表单

1、表单介绍

当我们在网页上填写账号密码进行登录的时候,就是在填写一个“表单”。web表单是web应用程序种最基本的功能。

2、表单的简单实现

下面的代码实现了这样的功能:

  • 前端发起请求时,收到一个含表单的网页
  • 在网页填写表单提交到后端
  • 后端对表单进行验证,显示成功或错误信息到前端

网页显示:

在这里插入图片描述

1. 代码

前端代码(index2.html):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <!-- 一个表单 -->
        <form method="post">
           <label>用户名:</label><input type="text" name="username"><br>
           <label>密码:</label><input type="password" name="password"><br>
           <label>确认密码:</label><input type="password" name="password2"><br>
           <input type="submit" value="提交"><br>
           <!-- 使用遍历获取闪现的消息 -->
           {% for message in get_flashed_messages() %}
               {{ message }}
           {% endfor %}
        </form>
    </body>
</html>

后端代码(python):

from flask import Flask, render_template, request, flash


app = Flask(__name__)

app.secret_key = 'qfmz'

'''
目的:实现一个简单的登录的逻辑处理
1. 路由需要有get和post两种请求方式 --> 需要判断请求方式
2. 获取请求的参数
3. 判断参数是否填写 & 密码是否相同
4. 如果判断都没有问题,就返回一个success
'''

'''
给模板传递消息
flash --> 需要对内容加密,因此设置secret_key,做加密消息的混淆
模板中遍历消息
'''

@app.route('/', methods=['GET', 'POST'])
def index():
    # request: 请求对象 --> 获取请求方式、数据

    # 1. 判断请求方式
    if request.method == 'POST':

        # 2. 获取请求参数
        username = request.form.get('username')
        password = request.form.get('password')
        password2 = request.form.get('password2')
        print(username)
        print(password)
        print(password2)
        
        # 3. 判断参数是否填写 & 密码是否相同
        if not all([username, password, password2]):
            flash('参数不完整')

        elif password != password2:
            flash('密码不一致')
        
        else:
            return 'success'

    # 2. 获取请求参数
    return render_template('index2.html')

app.run(debug=True)

2. 代码的执行逻辑

我填写一个表单时,这些代码的执行逻辑是怎样的呢?我知道这些代码能跑,但我总感觉自己和这些代码之间的隔阂较大,我不知道我在网页中的没一步操作是哪些代码在发挥作用。对此,debug单步执行是一个很有用的帮助理解的办法。

我知道,一个请求就对应着一个响应。那么总结下,进入一个网页,填写和提交表单的过程中应该是发生了2次请求,同时也有2次响应。

  • 第1次,我进入网页,网页对后端发送GET请求,后端判断请求类型不是POST,于是直接返回(不是返回html源代码,是在flask的模板引擎里走了一遭的)index2.html,前端就显示一个需要填写的表单。

  • 第2次,我填写完表单进行提交后,网页将表单中填写的数据作为参数,对后端发送POST请求,使用webob库解析environ得到的post参数如下:

    MultiDict([('username', '1'), ('password', '******'), ('password2', '******')])
    

    然后后端根据请求再返回一个网页到前端。

3、使用wtf扩展实现

显示效果与前面的“简单实现”一样,前端代码写起来会简单一些,后端的表单逻辑验证也可以直接使用库实现。

前端代码(index.html)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form method="post">
            {{ form.csrf_token() }}
            {{ form.username.label }}{{ form.username }}<br>
            {{ form.password.label }}{{ form.password }}<br>
            {{ form.password2.label }}{{ form.password2 }}<br>
            {{ form.submit }}
            <!-- 使用遍历获取闪现的消息 -->
            {% for message in get_flashed_messages() %}
                {{ message }}
            {% endfor %}
        </form>
    </body>
</html>

后端代码(python)

from flask import Flask, render_template, request, flash
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo


app = Flask(__name__)

app.secret_key = 'qfmz'


'''
使用WTF实现表单
自定义表单类
'''
class LoginForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired()])
    password = PasswordField('密码', validators=[DataRequired()])
    password2 = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password', '密码填入不一致!')])
    submit = SubmitField('提交')


@app.route('/', methods=['GET', 'POST'])
def login():
    login_form = LoginForm()
    # 1. 判断请求方式
    if request.method == 'POST':

        # 2. 获取请求参数
        username = request.form.get('username')
        password = request.form.get('password')
        password2 = request.form.get('password2')
        
        # 3. 逻辑验证,WTF一句话
        # 自动包含CSRF_token验证,前端代码记得写上{{ form.csrf_token() }}
        if login_form.validate_on_submit():
            print(username, password, password2)
            return 'success'
        else:
            flash('填写错误,请确保每项都填,且两次密码填写一致。')
        
    return render_template('index.html', form=login_form)


app.run(debug=True)

4、bug记录:表单验证总是失败

起初没加csrf时,以为是它的原因;后来加了还是失败,总以为是我csrf没写好,在网上搜csrf相关的文章和教程,然而令我没想到的是,最终问题是在验证函数EqualTo()这里,

# 问题代码
password2 = PasswordField('确认密码', validators=[DataRequired(), EqualTo(password, '密码填入不一致!')])
# 修改
password2 = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password', '密码填入不一致!')])

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

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

相关文章

Spring 面试题(一):Spring 如何处理全局异常?

❤️ 博客首页&#xff1a;水滴技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; &#x1f338; 订阅专栏&#xff1a;Spring 教程&#xff1a;从入门到精通 文章目录1、如何处理全局异常2、代码示例2.1、定义统一的“响应结果对象”2.2、…

Leetcode 回溯详解

回溯法 回溯法有“通用解题法”之称&#xff0c;用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。 在包含问题的所有解的解空间树中&#xff0c;按照深度优先搜索(DFS)&#xff09;的策略&#xff0c;从根结点出发深度探索解空间树。当探索…

MWORKS--同元软控MWORKS介绍、安装与使用

MWORKS--同元软控MWORKS介绍、安装与使用1 同元软控介绍1.1 同元软控简介1.2 同元软控发展历史2 MWORKS介绍2.1 MWORKS简介2.2 MWORKS产品描述3 装备数字化3.1 发展3.2 内涵3.3 系统模型发展成为产品的一部分3.4 MWORKS系统模型数据管理3.4 MWORKS为装备数字化提供的套件参考1 …

springcloud集成seata(AT)分布式事务

目录 一、 下载seata server和seata源码 二、配置启动seata 2.1 在nacos控制台&#xff0c;新建一个seata的名称空间&#xff0c;用于存放seata的专用配置 2.2 创建seata server的mysql库 2.3 在nacos上配置seata相关配置 &#xff08;seata名称空间&#xff09; 2.4 启动…

家政服务小程序实战教程08-宫格导航

小程序一般会在首页显示商品的分类&#xff0c;这类需求我们在微搭中是使用宫格导航组件来实现。 01 组件说明 宫格导航组件可以在导航配置里设置菜单&#xff0c;可以手动添加&#xff0c;也可以变量绑定 因为我们一般的分类是动态变化的&#xff0c;品类会不断的调整&#…

阿里代码规范插件中,Apache Beanutils为什么被禁止使用?

在实际的项目开发中&#xff0c;对象间赋值普遍存在&#xff0c;随着双十一、秒杀等电商过程愈加复杂&#xff0c;数据量也在不断攀升&#xff0c;效率问题&#xff0c;浮出水面。 问&#xff1a;如果是你来写对象间赋值的代码&#xff0c;你会怎么做&#xff1f; 答&#xf…

[Java 进阶面试题] CAS 和 Synchronized 优化过程

最有用的东西,是你手里的钱,有钱就有底气,还不快去挣钱~ 文章目录CAS 和 Synchronized 优化过程1. CAS1.1 CAS的原理1.2 CAS实现自增自减的原子性1.3 CAS实现自旋锁1.4 CAS针对ABA问题的优化2. synchronized2.1 synchronized加锁阶段分析2.2 synchronized优化CAS 和 Synchroniz…

nodejs+vue大学生在线选课系统vscode - Visual Studio Code

3、数据库进行设计&#xff0c;建立约束和联系。 4、创建程序框架&#xff0c;代码分成三层结构&#xff1a;接口层、业务层、表示层&#xff0c;设计窗口和主窗口&#xff0c;主窗口菜单项依照系统模块图设计。 5、设计数据访问的接口&#xff0c;供各模块调用。完成登录功能…

【JavaWeb项目】简单搭建一个前端的博客系统

博客系统项目 本项目主要分成四个页面: 博客列表页博客详情页登录页面博客编辑页 该系统公共的CSS样式 common.css /* 放置一些各个页面都会用到的公共样式 */* {margin: 0;padding: 0;box-sizing: 0; }/* 给整个页面加上背景 */ html, body{height: 100%; }body {backgrou…

printf的返回值

参考资料 点击下面的链接https://legacy.cplusplus.com/reference/cstdio/printf/?kwprintf, 返回值的理解 如果返回成功后&#xff0c;将返回写入的字符总数。 如果发生写入错误&#xff0c;则设置错误指示器&#xff08;ferror&#xff09;并返回负数。 如果在写入宽字符…

微信中如何接入chatgpt机器人才比较安全(不会收到警告或者f号)之第一步登录微信

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。 前言 为什么会有这个话题?大家都知道最近有个AI机器人很火,那就是chatgpt,关于它的介绍,大家可以自行百度去,我这边就不多介绍了。 好多人嫌网页版玩的不过瘾,就把这个机器人接入到了QQ上,接入到了钉钉上,TG 上…

设计模式:原型模式解决对象创建成本大问题

一、问题场景 现在有一只猫tom&#xff0c;姓名为: tom, 年龄为&#xff1a;1&#xff0c;颜色为&#xff1a;白色&#xff0c;请编写程序创建和tom猫属性完全相同的10只猫。 二、传统解决方案 public class Cat {private String name;private int age;private String color;…

JMeter 接口测试/并发测试/性能测试

Jmter工具设计之初是用于做性能测试的&#xff0c;它在实现对各种接口的调用方面已经做的比较成熟&#xff0c;因此&#xff0c;本次直接使用Jmeter工具来完成对Http接口的测试。因为再做接口测试时可以设置线程组&#xff0c;所以也可做接口性能测试。本篇使用JMeter完成了一个…

TrueNas篇-trueNas Scale安装

安装TrueNAS Scale 在尝试trueNas core时发下可以成功安装&#xff0c;但是一直无法成功启动&#xff0c;而且国内对我遇见的错误几乎没有案例&#xff0c;所以舍弃掉了&#xff0c;而且trueNas core是基于Linux的&#xff0c;对Linux的生态好了很多&#xff0c;还可以可以在t…

DNS 原理入门指南(二)

三、DNS服务器 下面我们根据前面这个例子&#xff0c;一步步还原&#xff0c;本机到底怎么得到域名math.stackexchange.com的IP地址。 首先&#xff0c;本机一定要知道DNS服务器的IP地址&#xff0c;否则上不了网。通过DNS服务器&#xff0c;才能知道某个域名的IP地址到底是什么…

Qt优秀开源项目之十六:SQLite数据库管理系统—SQLiteStudio

首先&#xff0c;感谢CSDN官方认可 SQLiteStudio是一款开源、跨平台&#xff08;Windows、Linux和MacOS&#xff09;的SQLite数据库管理系统。 github地址&#xff1a;https://github.com/pawelsalawa/sqlitestudio 官网&#xff1a;https://sqlitestudio.pl/ 特性很多&#xf…

11-git-查看提交历史

查看提交历史前言查看提交历史常用选项-p-n--stat--pretty--since限制输出选项前言 本篇来学习git中查看提交历史命令 查看提交历史 官方项目例子&#xff1a; git clone https://github.com/schacon/simplegit-progit git log说明: 不传任何参数会按时间先后顺序列出所有的…

Springboot+jsp齐鲁历史文化名人网站

山东地区是齐鲁文化的发源地,也是中华文明的摇篮之一 ,早在四十万年前这里 就开始出现了人类活动的遗迹(发现于沂源骑子鞍山南麓的沂源猿人头骨化石就是最好的证据)。另外,山东省境内的新泰、长岛、日照、蓬莱等地也都发现了旧石器时代晚期的人类化石。目前,山东史前文化的发掘…

C语言fopen函数的用法

在C语言中&#xff0c;操作文件之前必须先打开文件&#xff1b;所谓“打开文件”&#xff0c;就是让程序和文件建立连接的过程。打开文件之后&#xff0c;程序可以得到文件的相关信息&#xff0c;例如大小、类型、权限、创建者、更新时间等。在后续读写文件的过程中&#xff0c…

Selenium常用API详解,从入门到进阶(全套)

目录 1、打开页面 2、查找页面元素 3、输入文本 4、点击操作 5、提交操作 6、清除文本 7、获取文本、属性 8、获取页面的标题和URL 9、窗口 9.1、设置窗口大小 9.2、窗口切换 9.2.1、为什么需要窗口切换&#xff1f; 9.2.2、获取句柄的方式 9.2.3、切换句柄 10、…