【Flask】测试平台开发,产品管理实现添加功能-第五篇

 概述

在前面的几篇开发文章中,我们只是让数据在界面上进行了展示,但是没有添加按钮的功能,接下来我们需要开发一个添加的按钮,用户产品功能的创建和添加

  1. 抽公共数据链接方法

  2. 添加接口掌握post实现和请求数据处理

  3. 前端掌握Button\Dilog\Form\Input\Notification组件

服务端实现添加接口

封装数据库链接 在product.py 文件中我们需要增加一个create添加接口,不过再次之前我们需要先封装下面直接写在外边的数据链接对象,因为多方法中如增\改删使用完后会关闭数据库连接,所以不能一次声明到处使用,我们需要在每次接口请求处理业务前,进行新的数据库初始化,保证数据库正在链接状态。

def connectDB():connection = pymysql.connect(host='localhost',   # 数据库IP地址或链接域名user='root',     # 设置的具有增改查权限的用户password='', # 用户对应的密码database='tpmdatas',# 数据表charset='utf8mb4',  # 字符编码cursorclass=pymysql.cursors.DictCursor) # 结果作为字典返回游标return connection

增加添加接口 同之前的查询接口一样,我们设定新的route,用POST方法实现产品添加接口的处理,这里主要是掌握post的定义,以及请求传递的body如何处理,关键点如下:

  1. methods 定义为POST请求

  2. flask request模块的get_data()获取body

  3. json 请求处理请求的JSON格式数据

新增依赖引用

from flask import request
import json

添加功能的接口

@app_product.route("/api/product/create",methods=['POST'])
def product_create():# 初始化数据库链接connection = connectDB()# 定义默认返回结构体resp_data = {"code": 20000,"message": "success","data": []}# 获取请求传递json bodybody = request.get_data()body = json.loads(body)with connection:# 先做个查询,判断keyCode是否重复(这里的关键词最初定义为唯一项目编号或者为服务的应用名)with connection.cursor() as cursor:select = "SELECT * FROM `products` WHERE `keyCode`=%s AND `status`=0"cursor.execute(select, (body["keyCode"],))result = cursor.fetchall()# 有数据说明存在相同值,封装提示直接返回if len(result) > 0:resp_data["code"] = 20001resp_data["message"] = "唯一编码keyCode已存在"return resp_datawith connection.cursor() as cursor:# 拼接插入语句,并用参数化%s构造防止基本的SQL注入# 其中id为自增,插入数据默认数据设置的当前时间sql = "INSERT INTO `products` (`keyCode`,`title`,`desc`,`operator`) VALUES (%s,%s,%s,%s)"cursor.execute(sql, (body["keyCode"], body["title"], body["desc"], body["operator"]))# 提交执行保存插入数据connection.commit()# 按返回模版格式进行json结果返回return resp_data

添加新增接口之后,后端产品管理页面的完整代码如下

# -*- coding:utf-8 -*-from flask import Blueprint, jsonify
import pymysql.cursors
from flask import request
import json
from configs import config
from dbutils.pooled_db import PooledDBapp_product = Blueprint("app_product", __name__)# 使用用户名密码创建数据库链接
# PyMySQL使用文档  https://pymysql.readthedocs.io
def connectDB():connection = pymysql.connect(host=config.MYSQL_HOST,   # 数据库IP地址或链接域名user=config.MYSQL_USER,     # 设置的具有增改查权限的用户password=config.MYSQL_PASSWORD, # 用户对应的密码database=config.MYSQL_DATABASE,# 数据表charset='utf8mb4',  # 字符编码cursorclass=pymysql.cursors.DictCursor) # 结果作为字典返回游标# 返回新的书库链接对象return connection
// 获取列表数据展示的接口
@app_product.route("/api/product/list", methods=['GET'])
def product_list():# 初始化数据库链接connection = connectDB()# 使用python的with..as控制流语句(相当于简化的try except finally)with connection.cursor() as cursor:# 查询产品信息表-按更新时间新旧排序sql = "SELECT * FROM `products` WHERE `status`=0 ORDER BY `update` DESC"cursor.execute(sql)data = cursor.fetchall()# 按返回模版格式进行json结果返回resp_data = {"code": 20000,"data": data}return resp_data// 添加产品功能的接口
@app_product.route("/api/product/create",methods=['POST'])
def product_create():# 初始化数据库链接connection = connectDB()# 定义默认返回结构体resp_data = {"code": 20000,"message": "success","data": []}# 获取请求传递json bodybody = request.get_data()body = json.loads(body)with connection:# 先做个查询,判断keyCode是否重复(这里的关键词最初定义为唯一项目编号或者为服务的应用名)with connection.cursor() as cursor:select = "SELECT * FROM `products` WHERE `keyCode`=%s AND `status`=0"cursor.execute(select, (body["keyCode"],))result = cursor.fetchall()# 有数据说明存在相同值,封装提示直接返回if len(result) > 0:resp_data["code"] = 20001resp_data["message"] = "唯一编码keyCode已存在"return resp_datawith connection.cursor() as cursor:# 拼接插入语句,并用参数化%s构造防止基本的SQL注入# 其中id为自增,插入数据默认数据设置的当前时间sql = "INSERT INTO `products` (`keyCode`,`title`,`desc`,`operator`) VALUES (%s,%s,%s,%s)"cursor.execute(sql, (body["keyCode"], body["title"], body["desc"], body["operator"]))# 提交执行保存插入数据connection.commit()# 按返回模版格式进行json结果返回return resp_data

对于产品添加中有个字段keyCode我们需求上定义为项目唯一编码,所以对于插入不应该有重复项,所以我们需要在正式插入操作前进行查询判断,如果重复给出提示,code 定义20001,那么在前端request.js 进行处理的时候,由于不是20000就会拦截,并按照message内容错误提示。

以上编写完成再次用ide或者命令运行 app.py 启动后端程序,用postman进行请求测试,验证产品新增接口服务没有问题

1)重复提示

前端实现添加功能

先看下想要实现成的页面样式

定义接口请求 首先对已经测试通过添加接口定义到前端src/api/product.js中,这里主要就是学会post请求接口的方式,以及注意参数定义,在查询定义下方,新增如下定义

data: 就是请求的json格式的参数,稍后在前端定义

export function apiProductCreate(requestBody) {return request({url: '/api/product/create',method: 'post',data: requestBody})
}

定义请求参数 在 product.vue页面script中的data()返回数据集里定义

  • 一个变量获取之前登录的用户名后边作为操作者值

  • 定义product的json,默认赋值undefined,操作人赋予op_user

  • dialogProductShow 用户添加对话框的显示和隐藏属性变量

// 导入全局存储
import store from '@/store'
     op_user: store.getters.name,// 定义产品参数product: {id: undefined,title: undefined,keyCode: undefined,desc: undefined,operator: this.op_user},// 控制嵌套表单显示和隐藏dialogProductShow: false,

这里要清楚一点是,其他变量的引用需要通过this.来给定

定义添加按钮 直接使用element-ui的button组件,在原来界面table之上定义,使用的图标按钮,掌握 el-button 另外对于组件的使用,初期都在想用什么的时候直接去官方参考就行。


<div class="filter-container">      
<el-button type="primary" icon="el-icon-plus" style="float:right" @click="dialogProduct()">新增</el-button>
</div>

属性type=为类型,主要就是不同样式;

icon=内部的一些图标,见icon图标组件说明;

style= 就是自定义的css样式了

@click 指定点击的时候的动作 dialogProduct() 执行下边边自定义方法

其他按钮样式或属性参考官网:https://element.eleme.io/#/zh-CN/component/button

实现dialogProduct()方法 在product.vue 中的 methods模块中,增加初始化数据和显示增加对话框页面逻辑

dialogProduct() {// 添加先初始化空状态this.product.id = undefinedthis.product.keyCode = ''this.product.title = ''this.product.desc = ''this.product.operator = this.op_user// 弹出对话框设置为truethis.dialogProductShow = true},

页面实现添加窗体 使用Dialog组件和嵌套form来实现创建表单的页面,掌握el-dialog 、 el-form 和el-input 三个组件,再定义两个button按钮实现取消/确定的操作逻辑

<!--对话框嵌套表,使用el-dialog--><el-dialog title="添加产品或项目" :visible.sync="dialogProductShow"><el-form :model="product"><el-form-item label="名称" label-width="100px"><el-input v-model="product.title" placeholder="请填写中文名称" style="width: 80%"></el-input></el-form-item><el-form-item  label="唯一码" label-width="100px"><el-input v-model="product.keyCode" placeholder="产品/项目唯一码" style="width: 80%"></el-input></el-form-item><el-form-item  label="备注" label-width="100px"><el-input v-model="product.desc" type="textarea" placeholder="备注说明" style="width: 80%"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="dialogProductShow = false">取 消</el-button><el-button type="primary" @click="pCreate()">确 定</el-button></span></el-dialog>

本例 :visible.sync="dialogProductShow" 属性绑定上边定义的变量,控制是否显示此对话框,flase为隐藏,true为显示;

:model="product" 动态数据绑定 v-model 子数据绑定;

label="" 标题;placeholder="" 输入框内部提示说明;

type="textarea" 输入组件指定为多行文本框;

其他按钮样式或属性参考官网:

https://element.eleme.io/#/zh-CN/component/dialog

https://element.eleme.io/#/zh-CN/component/form

https://element.eleme.io/#/zh-CN/component/input

实现pCreate()方法 最终弹窗内容填写后,点击确定按钮触发真正的保存操作,由于vue已经在上边动态的显示数据绑定,所以参考之前查询操作,这里请求apiProductCreate 并给定data()中的product请求数据即可,本列掌握传参接口请求,以及成功后的 Notification 组件

引入api

// 导入src/api/proudct 配置的请求列表方法
import { apiProductList, apiProductCreate } from '@/api/product'

具体代码实现和其他逻辑处理

 pCreate() {// 请求API进行添加apiProductCreate(this.product).then(response => {// 如果request.js没有拦截即表示成功,给出对应提示和操作this.$notify({title: '成功',message: '项目或产品添加成功',type: 'success'})// 关闭对话框this.dialogProductShow = false// 重新查询刷新数据显示this.getProductList()})},

https://element.eleme.io/#/zh-CN/component/notification

顺利敲下来,就可以npm run dev 启动查看最终效果了,如测接口一样,分别测试下重复添加和正常添加功能是否OK。

经过我们测试下来,添加功能正常使用,命名和唯一编码也有去重处理,相同code不能重复添加,另外我们在对于项目名称和唯一标识符做下前端输入显示,不能为空输入提示

添加了输入必填校验,使得功能更加完善

 

 

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

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

相关文章

循环高级(2)

6.练习3 打印九九乘法表7.练习3 制表符详解对齐不了原因&#xff1a;name补到8zhangsan本身就是8&#xff0c;补完就变成16解决办法&#xff1a;1.去掉zhangsan\t,这样前后都是82.name后面加2个\t加一个\t&#xff0c;name\t就是占8个&#xff0c;再加一个\t&#xff0c;就变成…

盒马生鲜 小程序 逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 部分python代码 params {&…

【Linux系统】线程控制

1. POSIX线程库 (pthreads)POSIX线程&#xff08;通常称为pthreads&#xff09;是IEEE制定的操作系统线程API标准。Linux系统通过glibc库实现了这个标准&#xff0c;提供了创建和管理线程的一系列函数。核心特性命名约定&#xff1a;绝大多数函数都以 pthread_ 开头&#xff0c…

【Spring Cloud Alibaba】前置知识

【Spring Cloud Alibaba】前置知识1. 微服务介绍1.1 系统架构的演变1.1.1 单体应用架构1.1.2 垂直应用架构1.1.3 分布式架构1.1.3.1 SOA架构1.1.4 微服务架构1. 微服务介绍 1.1 系统架构的演变 随着互联网的发展&#xff0c;网站应用的规模也在不断的扩大&#xff0c;进而导致…

2025互联网大厂Java面试1000道题目及参考答案

Java学到什么程度可以面试工作&#xff1f; 要达到能够面试Java开发工作的水平&#xff0c;需要掌握以下几个方面的知识和技能&#xff1a; 1. 基础扎实&#xff1a;熟悉Java语法、面向对象编程概念、异常处理、I/O流等基础知识。这是所有Java开发者必备的基础&#xff0c;也…

记录:HSD部署(未完成)

建数据库 相关文档&#xff1a;Confluence准备&#xff1a;CA文件和备份用的aws key。 CA文件&#xff1a;在namespace添加trust-injectionenabled的标签&#xff0c;会自动生成。 aws key&#xff1a;生成cnpg-backup-creds的secret。安装&#xff1a; 从git仓库获取values模…

【AI】提示词与自然语言处理:从NLP视角看提示词的作用机制

提示词与自然语言处理&#xff1a;从 NLP 视角看提示词的作用机制在人工智能快速发展的今天&#xff0c;大模型成为了人们关注的焦点。而要让大模型更好地理解人类意图、完成各种任务&#xff0c;提示词扮演着关键角色。从自然语言处理&#xff08;NLP&#xff09;的角度来看&a…

2025.8.29机械臂实战项目

好久没给大家更新了&#xff0c;上周末大学大四开学&#xff0c;所以停更了几天&#xff0c;回来后在做项目&#xff0c;接下来的几篇文章&#xff0c;给大家带来几个项目&#xff0c;第一个介绍的是机械臂操作&#xff0c;说是机械臂操作&#xff0c;简单来说&#xff0c;就是…

【机器学习基础】机器学习的要素:任务T、性能度量P和经验E

第一章 机器学习的本质与理论框架 机器学习作为人工智能领域的核心支柱,其理论基础可以追溯到20世纪中叶的统计学习理论。Tom Mitchell在其1997年的经典著作《Machine Learning》中给出了一个至今仍被广泛引用的学习定义:"对于某类任务T和性能度量P,一个计算机程序被认…

wav音频转C语言样点数组

WAV to C Header Converter 将WAV音频文件转换为C语言头文件的Python脚本&#xff0c;支持将音频数据嵌入到C/C项目中。 功能特性 音频格式支持 PCM格式&#xff1a;支持8位、16位、24位、32位PCM音频IEEE Float格式&#xff1a;支持32位浮点音频多声道&#xff1a;支持单声道、…

01.《基础入门:了解网络的基本概念》

网络基础 文章目录网络基础网络通信核心原理网络通信定义信息传递过程关键术语解释网络的分类网络参考模型OSI 参考模型各层核心工作分层核心原则TCP/IP 参考模型&#xff08;4 层 / 5 层&#xff0c;实际应用模型&#xff09;TCP/IP 与 OSI 模型的对应关系传输层核心协议&…

基于vue驾校管理系统的设计与实现5hl93(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表&#xff1a;项目功能&#xff1a;学员,教练,教练信息,预约信息,场地信息,时间安排,车辆信息,预约练车,时间段,驾校场地信息,驾校车辆信息,预约报名开题报告内容&#xff1a;一、选题背景与意义背景随着汽车保有量持续增长&#xff0c;驾校行业规模不断扩大&am…

灰度思维:解锁世界原有本色的密码

摘要本文深入探讨灰度思维的概念内涵及其在处理他人评价中的应用价值。研究指出&#xff0c;灰度思维作为一种超越非黑即白的思维方式&#xff0c;能够帮助个体以更客观、全面的态度接受他人评价的片面性&#xff0c;从而促进个人成长和人际关系和谐。文章分析了他人评价片面性…

动态规划--Day03--打家劫舍--198. 打家劫舍,213. 打家劫舍 II,2320. 统计放置房子的方式数

动态规划–Day03–打家劫舍–198. 打家劫舍&#xff0c;213. 打家劫舍 II&#xff0c;2320. 统计放置房子的方式数 今天要训练的题目类型是&#xff1a;【打家劫舍】&#xff0c;题单来自灵艾山茶府。 掌握动态规划&#xff08;DP&#xff09;是没有捷径的&#xff0c;咱们唯一…

Nuxt.js@4 中管理 HTML <head> 标签

可以在 nuxt.config.ts 中配置全局的 HTML 标签&#xff0c;也可以在指定 index.vue 页面中配置指定的 HTML 标签。 在 nuxt.config.ts 中配置 HTML 标签 export default defineNuxtConfig({compatibilityDate: 2025-07-15,devtools: { enabled: true },app: {head: {charse…

UCIE Specification详解(十)

文章目录4.5.3.7 PHYRETRAIN&#xff08;物理层重训练&#xff09;4.5.3.7.1 Adapter initiated PHY retrain4.5.3.7.2 PHY initiated PHY retrain4.5.3.7.3 Remote Die requested PHY retrain4.5.3.8 TRAIN ERROR4.5.3.9 L1/L24.6 Runtime Recalibration4.7 Multi-module Link…

电商数据的获取方式:API、爬虫、第三方服务及更多

在竞争激烈的电商领域&#xff0c;数据是驱动业务增长的关键。准确、及时地获取电商数据&#xff0c;并进行深入分析&#xff0c;能够帮助企业洞察市场趋势、优化运营策略、提升用户体验。本文将全面介绍电商数据的获取方式&#xff0c;涵盖API接口、网络爬虫技术、第三方数据服…

《WINDOWS 环境下32位汇编语言程序设计》第8章 通用对话框

Windows操作系统为一些常用功能提供了一些通用对话框&#xff08;Common Dialog Box&#xff09;&#xff0c;比如&#xff0c;在不同的应用程序中进行打开文件、选择字体、选择颜色等操作时&#xff0c;不同程序显示的对话框的模样都是一样的。另外&#xff0c;把同样的应用程…

SOME/IP-SD协议中组播IP地址和端口号应从何处获取、由谁设置?

<摘要> AUTOSAR SOME/IP-SD协议中组播通信参数的核心配置规则明确规定了在服务端传输&#xff08;Server-Transmits&#xff09;和客户端传输&#xff08;Client-Transmits&#xff09;两种模式下&#xff0c;组播IP地址和端口号应从何处获取、由谁设置&#xff0c;从而确…

DAY49打卡

追到第45天内容浙大疏锦行