【开源】使用Python+Flask+Mysql快速开发一个用户增删改查系统

项目演示

项目本身很简单,增删改查是几乎所有系统的骨架。正所谓万丈高楼平地起,学会了增删改查,航母就指日可待了:),光速入门,直接看演示图:
在这里插入图片描述

项目地址

https://github.com/mudfish/python-flask-user-crud

Flask框架介绍

说白了就是一个Web框架,能够让你快速开发出Python web应用。简单易用,大家直接看官网就行:
https://flask.palletsprojects.com/en/3.0.x/quickstart/

开发步骤

开发工具

懒得折腾Pycharm了,直接Vscode安装pyhon和flask插件即可,也是比较丝滑的。

准备静态文件

主要用了Bootstrap5和Jquery这两个前端框架,一个是UI,一个是js。
都放到static文件夹下面:
在这里插入图片描述

开发入口文件

这个就是flask运行的文件,里面包括了启动入口,端口号和业务逻辑接口。
在这里插入图片描述

from flask import Flask, render_template, request, redirect, url_for, flash
import pymysql.cursors



# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='root',
                             password='123456',
                             db='user_test',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
    
app = Flask(__name__)

# 保持数据库连接
def getconnection():
    connection.ping(reconnect=True)
    return connection
    
# 首页
@app.route('/')
def index():
    try:
        with getconnection().cursor() as cursor:
            sql = "SELECT * FROM `tb_user`"
            cols = ['id', 'name', 'age','gender','phone']
            cursor.execute(sql)
            result = cursor.fetchall()
            cursor.close()
            return render_template("index.html", items=result, cols=cols, success='')
    except Exception as e:
        cursor.close()
        return render_template("index.html", items=[], cols=[], success='Can\'t view index: ' + str(e))
    
# 搜索
@app.route('/search')
def search():
    keyword = request.args.get('keyword').strip()
    try:
        with getconnection().cursor() as cursor:
            sql = "SELECT * FROM `tb_user` where name like concat('%%',%s,'%%')"
            cols = ['id', 'name', 'age','gender','phone']
            cursor.execute(sql,(keyword))
            result = cursor.fetchall()
            # print(result)
            cursor.close()
            return render_template("index.html", items=result, keyword=keyword, cols=cols, success='')
    except Exception as e:
        cursor.close()
        return render_template("index.html", items=[], cols=[], success='search error: ' + str(e))


@app.route('/toAddPage')
def toAddPage():
 return render_template('add.html')

@app.route('/toEditPage/<int:id>')
def toEditPage(id):
    # print(id)
    try:
        with getconnection().cursor() as cursor:
            sql = "select * from `tb_user` where id=%s"
            cursor.execute(sql, (id))
            result = cursor.fetchone()
            cursor.close()
            return render_template("edit.html", item=result, success='')
    except Exception as e:
        cursor.close()
        return render_template("edit.html", success='Can\'t edit User: ' + str(e))

@app.route('/add', methods=['POST'])
def add():
    name = request.form['name'].strip()
    age = request.form['age'].strip()
    gender = request.form['gender'].strip()
    phone = request.form['phone'].strip()
    try:
        with getconnection().cursor() as cursor:
            sql = "INSERT INTO `tb_user` (`name`, `age`,`gender`,`phone`) VALUES (%s, %s,%s,%s)"
            cursor.execute(sql, (name, age,gender,phone))
            cursor.close()
            return redirect(url_for("index"))
    except Exception as e:
        cursor.close()
        return render_template("add.html", success='Can\'t add User: ' + str(e))

@app.route('/edit',methods=['POST'])
def edit():
    id = request.form['id'].strip()
    name = request.form['name'].strip()
    age = request.form['age'].strip()
    phone = request.form['phone'].strip()
    gender = request.form['gender'].strip()
    try:
        with getconnection().cursor() as cursor:
            sql = "update `tb_user` set name=%s,age=%s,gender=%s,phone=%s where id=%s"
            cursor.execute(sql, (name, age,gender,phone,id))
            cursor.close()
            return redirect(url_for("index"))
    except Exception as e:
        cursor.close()
        return render_template("edit.html", success='Can\'t edit User: ' + str(e))

@app.route('/remove/<int:id>/')
def remove(id):
    try:
        with getconnection().cursor() as cursor:
            sql = "delete from `tb_user` where id=%s"
            cursor.execute(sql, (id))
            cursor.close()
            return redirect(url_for("index"))
    except Exception as e:
        cursor.close()
        return render_template("index.html", success='Can\'t remove User: ' + str(e))

@app.errorhandler(404)
def page_not_found(error):
    return render_template('page_not_found.html'), 404

@app.errorhandler(500)
def system_error(error):
    return render_template('500.html'), 500

if __name__ == '__main__':
    # 静态文件缓存自动刷新
    app.jinja_env.auto_reload = True
    app.run(host='127.0.0.1',port=8001, debug=True)

开发html文件

后端接口有了,接下来就是web端发起调用,完成增删改查交互操作了。
此处flask提供了简单易用的渲染语法,请看:

首页

<!DOCTYPE html>
<html lang="en">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}"
           rel="stylesheet">
       <title>首页</title>
   </head>
   <body>
       <div class="container">
           <div class="row justify-content-center align-items-center g-1">
               <div class="col-6 pt-5">
                   <!-- search -->
                   <form action="/search" method="get">
                       <div class="input-group mb-3">
                           <input type="text" class="form-control" placeholder
                               aria-label="Example text with button addon"
                               aria-describedby="button-addon1" name="keyword" {% if keyword%} value="{{keyword}}" {% endif %}>
                           <button class="btn btn-primary" type="submit"
                               id="button-addon1">查询</button>
                               <a class="btn btn-warning " href="/toAddPage">新增</a>
                       </div>
                   </form>

                   

                   <div
                       class="table-responsive">
                       <table
                           class="table table-primary">
                           <thead>
                               <tr>
                                   <th scope="col">ID</th>
                                   <th scope="col">姓名</th>
                                   <th scope="col">性别</th>
                                   <th scope="col">年龄</th>
                                   <th scope="col">联系方式</th>
                                   <th scope="col">操作</th>
                               </tr>
                           </thead>
                           <tbody>
                               {% for item in items %}
                               <tr>
                                   {% for col in cols %}
                                   <td>{{ item[col] }}</td>
                                   {% endfor %}
                                   <!-- 补操作列 -->
                                   <td>
                                       <a class="btn btn-sm btn-primary"
                                           href="{{url_for('toEditPage',id=item['id'])}}">编辑</a>
                                       <a class="btn btn-sm btn-danger"
                                           href="{{url_for('remove',id=item['id'])}}"
                                           onclick="return confirm('确定删除吗');" >删除</a>
                                   </td>
                               </tr>
                               {% endfor %}

                           </tbody>
                       </table>
                       <div class="bg-warning  ">{{success}}</div>

                   </div>
               </div>
           </div>
       </div>

       <script
           src="{{url_for('static',filename='js/jquery.min.js')}}"></script>

   </body>
</html>

新增页面

<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>新增用户</title>
   <link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}"
     rel="stylesheet">
 </head>
 <body>
   <div class="container">
     <div class="row justify-content-center align-items-center g-1">
       <div class="col-6 pt-5">
         <div class="card">
           <div class="card-header">
             新增用户
           </div>
           <div class="card-body">

             <form action="/add" method="post">
               <div class="row mb-3">
                 <label for="colFormLabelSm"
                   class="col-sm-2 col-form-label col-form-label">姓名</label>
                 <div class="col-sm-10">
                   <input type="text" class="form-control form-control-sm"
                     id="colFormLabelSm" name="name" required>
                 </div>
               </div>
               <div class="row mb-3">
                 <label for="age" class="col-sm-2 col-form-label">年龄</label>
                 <div class="col-sm-10">
                   <input type="text" class="form-control" id="age" name="age"
                     required>
                 </div>
               </div>
               <div class="row mb-3">
                 <label for="inlineRadio1"
                   class="col-sm-2 col-form-label">性别</label>
                 <div class="col-3">
                   <input class="form-check-input" type="radio" name="gender"
                     id="gender01" value="">
                   <label class="form-check-label" for="inlineRadio1"></label>
                 </div>
                 <div class="col-2">
                   <input class="form-check-input" type="radio" name="gender"
                     id="gender02" value="">
                   <label class="form-check-label" for="inlineRadio2"></label>
                 </div>
               </div>
               <div class="row mb-3">
                 <label for="phone"
                   class="col-sm-2 col-form-label">联系电话</label>
                 <div class="col-sm-10">
                   <input type="text" class="form-control" id="phone"
                     name="phone" required>
                 </div>
               </div>
               <div
                 class="row mb-3 justify-content-center align-items-center ">
                 <div class="col-6">
                   <a type="button" class="btn btn-secondary " href="/">
                     取消
                   </a>
                   <button type="submit" class="btn btn-primary ">
                     保存
                   </button>
                 </div>

               </div>
             </form>

           </div>

           <div class="bg-warning  ">{{success}}</div>
         </div>
       </div>

     </div>
   </div>
 </body>
</html>

编辑页面

<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>修改用户</title>
   <link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}"
     rel="stylesheet">
 </head>
 <body>
   <div class="container">
     <div class="row justify-content-center align-items-center g-1">
       <div class="col-6 pt-5">
         <div class="card">
           <div class="card-header">
             新增用户
           </div>
           <div class="card-body">
             <form action="/edit" method="post">
               {% if item %}
               <input type="hidden" name="id" value="{{item.id}}">
               <div class="row mb-3">
                 <!-- {{item}} -->
                 <label for="colFormLabelSm"
                   class="col-sm-2 col-form-label col-form-label">姓名</label>
                 <div class="col-sm-10">
                   <input type="text" class="form-control form-control-sm"
                     id="colFormLabelSm" name="name" value="{{item.name}}"
                     required>
                 </div>
               </div>
               <div class="row mb-3">
                 <label for="age" class="col-sm-2 col-form-label">年龄</label>
                 <div class="col-sm-10">
                   <input type="text" class="form-control" id="age" name="age"
                     value="{{item.age}}" required>
                 </div>
               </div>
               <div class="row mb-3">
                 <label for="gender" class="col-sm-2 col-form-label">性别</label>
                 <div class="col-3">
                   <input class="form-check-input" type="radio" name="gender"
                     id="gender01" value="男" {% if item.gender=="男" %} checked
                     {% endif %}>
                   <label class="form-check-label" for="gender01"></label>
                 </div>
                 <div class="col-2">
                   <input class="form-check-input" type="radio" name="gender"
                     id="gender02" value="女" {% if item.gender=="女" %} checked
                     {% endif %}>
                   <label class="form-check-label" for="gender02"></label>
                 </div>
               </div>
               <div class="row mb-3">
                 <label for="phone"
                   class="col-sm-2 col-form-label">联系电话</label>
                 <div class="col-sm-10">
                   <input type="text" class="form-control" id="phone"
                     name="phone" value="{{item.phone}}" required>
                 </div>
               </div>
               <div
                 class="row mb-3 justify-content-center align-items-center ">
                 <div class="col-6">
                   <a type="button" class="btn btn-secondary  " href="/">
                     取消
                   </a>
                   <button type="submit" class="btn btn-primary ">
                     保存
                   </button>
                 </div>
               </div>
               {% endif %}
             </form>
           </div>
         </div>
         <div class="bg-warning  ">{{success}}</div>
       </div>
     </div>
   </div>
 </body>
</html>

收工

看完觉着有帮助的朋友,一键三连哈~~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Golang】Gin教学-获取请求信息并返回

安装Gin初始化Gin处理所有HTTP请求获取请求的URL和Method获取请求参数根据Content-Type判断请求数据类型处理JSON数据处理表单数据处理文件返回JSON响应启动服务完整代码测试 Gin是一个用Go&#xff08;又称Golang&#xff09;编写的HTTP Web框架&#xff0c;它具有高性能和简洁…

npx\pnpm 镜像过期解决方法

. // 1. 清空缓存 npm cache clean --force // 2. 关闭SSL验证 npm config set strict-ssl false // 3. 安装 到这里就可以正常使用npm命令安装需要的工具了。如( npm install -g cnpm )

华为机考入门python3--(17)牛客17- 坐标移动

分类&#xff1a;字符串 知识点&#xff1a; 正则匹配 re.match(pattern, move) 格式字符串&#xff0c;可以在字符串中直接引用变量 f"{x},{y}" 题目来自【牛客】 import re def is_valid_coordinate(move): # 使用正则表达式验证移动是否合法 # ^: …

面试: Hashtable vs ConcurrentHashMap

一、Hashtable和ConcurrentHashMap的不同和相同点 Hashtable 与 ConcurrentHashMap 都是线程安全的Map 集合。Hashtable 并发度低&#xff0c;整个Hashtable对应一把锁&#xff0c;同一时刻&#xff0c;只能有一个线程操作它。1.8之前ConcurrentHashMap使用了Segment 数组&…

缓存的使用及常见问题的解决方案

用户通过浏览器向我们发送请求&#xff0c;这个时候浏览器就会建立一个缓存&#xff0c;主要缓存一些静态资源&#xff08;js、css、图片&#xff09;&#xff0c;这样做可以降低之后访问的网络延迟。然后我们可以在Tomcat里面添加一些应用缓存&#xff0c;将一些从数据库查询到…

解决Keil V5.38 和 ST-Link V3 Debug不能运行问题

目录 概述 1 问题描述 1.1 情况一 1.2 情况二 1.3 情况三 2 解决方法 2.1 认识Keil Mico Lib 2.2 使能Keil Mico Lib 3 验证 3.1 进入C程序Main验证 3.2 断点验证 3.3 上电重启验证 4 结论 笔者使用的验证代码下载地址&#xff1a; stm32-freeRTOS-queue资源-CSD…

顺序表链表经典算法题

1.链表反转 typedef struct ListNode listnode; struct ListNode* reverseList(struct ListNode* head) {if(head NULL){return head;}listnode* p1 NULL;listnode* p2 head;listnode* p3 head->next;while(p2){p2->next p1;p1 p2;p2 p3;if(p3)p3 p3->next;}…

使用 Godot 游戏引擎为 Apple 的 visionOS 创建游戏和应用的平台

借助GodotVision ,您可以使用Godot 游戏引擎为 Apple VisionOS创建游戏和应用程序。 保卫牛城堡,一款使用 GodotVision 制作的 VisionOS 游戏 GodotVision 运行一个控制本机RealityKit 视图的无头 Godot实例。粗略地说:Godot 是后端,

二百三十三、Flume——Flume采集JSON文件到Kafka,再用Flume采集Kafka数据到HDFS中

一、目的 由于使用了新的Kafka协议&#xff0c;因为根据新的协议推送模拟数据到Kafka中&#xff0c;再Flume采集Kafka数据到HDFS中 二、技术选型 &#xff08;一&#xff09;Kettle工具 准备使用Kettle的JSON input控件和Kafka producer控件&#xff0c;但是搞了1天没搞定&…

如何用idm下载迅雷文件 idm怎么安装到浏览器 idm怎么设置中文

如果不是vip用户使用迅雷下载数据文件&#xff0c;其下载速度是很慢的&#xff0c;有的时候还会被限速&#xff0c;所以很多小伙们就开始使用idm下载迅雷文件&#xff0c;idm这款软件最大的优势就是下载速度快&#xff0c;还有就是具备网页捕获功能&#xff0c;能够下载网页上的…

【uniapp】 合成海报组件

之前公司的同事写过一个微信小程序用的 合成海报的组件 非常十分好用 最近的项目是uni的 把组件改造一下也可以用 记录一下 <template><view><canvas type"2d" class"_mycanvas" id"my-canvas" canvas-id"my-canvas" …

全开源小狐狸Ai系统 小狐狸ai付费创作系统 ChatGPT智能机器人2.7.6免授权版

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.4、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态thinkPHP&#xff0c;开启ssl证书 具有文章改写、广告营销文案、编程…

Windows:web端UI自动化=python+selenium+pycharm框架

本篇写怎么写一个UI自动化代码。mac和Windows是一样的 都是这样写 不过&#xff0c;习惯用Windows了 如果python没有安装可以看我另一篇安装python的教程 先安装python先 下载完python 下载pip 1 安装pip $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py # 下载…

宝塔面板使用docker+nginx+gunicorn部署Django项目实战教程

第一步&#xff1a;创建Django项目 使用pip install django安装创建django项目的依赖在电脑某个根目录下执行django-admin startproject app创建一个名为app的Django项目。目录结构如下: ├── app │ ├── init.py │ ├── asgi.py │ ├── settings.py │ ├── url…

机器学习:考试复习提纲

该页仅为复习资料&#xff0c;内含博客链接均通过搜索得到。 当然直接访问我的GitHub博客会更方便。 1. 线性回归 Linear Regression https://www.cnblogs.com/geo-will/p/10468253.html 要求1&#xff1a;可以按照自己的理解简述线性回归问题。 回归分析是一种预测性的建模…

buuctf re 37-40

[WUSTCTF2020]Cr0ssfun 打开 #include<iostream> using namespace std; int main() {char a1[32];a1[1] c;a1[25] ; a1[27] e;a1[4] 2;a1[17] r;a1[29] f;a1[17] r;a1[24] _;a1[2] t;a1[9] c;a1[32] };a1[19] v;a1[5] 0;a1[14] n;a1[15] d;a1[8] {;a1[18]…

【Leetcode每日一题】 动态规划 - 地下城游戏(难度⭐⭐⭐)(61)

1. 题目解析 题目链接&#xff1a;174. 地下城游戏 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 一、状态表定义 在解决地下城游戏问题时&#xff0c;我们首先需要对状态进行恰当的定义。一个直观的想法是&#x…

Oracle EBS Interface/API(54)- GL日记账审批

背景: 客户化创建薪酬凭证或者银企付款入账日记账以后,用户希望自动提交审批流程,无需到系统标准功能点击审批,减少用户操作。 快速参考 参考点内容功能导航N: GL->日记账->输入并发请求None基表GL.GL_JE_BATCHESAPI参考下面介绍错误信息表None接口FormNone接口Reque…

wiringpi库的应用 -- sg90 定时器 oled

sg 90舵机: 接线: VCC -- 红 GND -- 地 信号线 -- 黄 -- pwm 定时器: 先玩定时器: sg90 需要的pwm波需要定时器输出&#xff0c;so我们得先来玩一下定时器 分析&#xff1a;实现定时器&#xff0c;通过itimerval结构体以及函数setitimer产生的信号&#xff0c;系统…

Flume在大数据集群下的配置以及监控工具Ganglia的部署安装

前提&#xff1a;需要有三台虚拟机&#xff08;hadoop102,103,104&#xff09;配置好相关基础环境 安装 将安装包上传到/opt/software中 tar -zxf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/修改 apache-flume-1.9.0-bin 的名称为 flume mv /opt/module/…