0


使用python的flask框架做一个本地mysql服务器的webui!

该webui的主要作用是作为一个数据库管理系统对本地mysql数据库进行管理。这里会手把手教学如何实现的,并在文末给出初代完整flask数据库管理系统的完整代码!希望能帮助到有需要的同学。本来是想用来干点其他的,但是想了一下决定还是完整开源出来,各位看官,用的话记得给个鸣谢或者引用呗!Thanks♪(・ω・)ノ

注:本人软工部分也是刚学习不久,代码规范和代码维护上存在欠缺,还需看官多多包涵,恳请批评指正!

这是我的界面截图(背景随便找的)

登录界面:

数据库选择界面:

数据库管理界面:

搜索结果:

现在我们开始

首先,先安装mysql数据库,这里给出一个windows的下载链接,我选择的是mysql8.4.0.lts版本,MySQL :: Download MySQL Community Server

以及mysql workbench-mysql的可视化界面

MySQL :: Download MySQL Workbench

下载后根据安装指引安装即可,记得先给设置一个从用户账户和密码,该账户用来给flask连接数据库。记住保存路径,并勾选world数据库(方便后期调试)

然后设置系统环境变量,右键此电脑→高级系统设置→系统变量设置→系统变量→path→新建→粘贴刚才的保存路径(默认是C:\Program Files\MySQL\MySQL Server 8.4\bin,需要查看该目录下是否存在mysql.exe)

mysql安装好后按道理理论上会自动启动,不过也可以通过win+r输入services.msc查询,找到mysql开头的,我的是MySQL84,右键属性可以看到

这样就可以了。

然后试一下,找一个空白的地方shift+右键,打开powershell,然后键入 mysql -u root账户名 -p,然后输入密码验证。显示<mysql>即成功安装。

然后就是python,python的安装自行搜索,不做过多停留,安装完python后给pip换为国内源,

windows环境下: 比如windows账号是 admin

那么建立 admin主目录下的 pip子目录,在此pip子目录下建立pip的配置文件:pip.ini

位于c:\users\admin\pip\pip.ini

coding: GBK

[global]

index-url = https://pypi.tuna.tsinghua.edu.cn/simple

[install]

trusted-host = https://pypi.tuna.tsinghua.edu.cn

#清华大学:https://pypi.tuna.tsinghua.edu.cn/simple

#阿里云:http://mirrors.aliyun.com/pypi/simple/

#豆瓣:http://pypi.douban.com/simple/

=================================================================

推荐采用python虚拟环境中执行该系统环境配置

创建一个工程目录,并在该目录下执行powershell(shift + 右键)或者终端(ctrl+alt+T)

python -m venv venv

venv/script/activate

安装flask框架(mysql):
pip install flask
pip install mysql-connector-python
pip install Flask mysql-connector-python
pip install Flask-Session

这样环境就配置好了

然后就是执行python文件,python app.py

如果终端显示

则表示运行成功,并可在浏览器输入http://127.0.0.1:5000访问。

以下是app.py的示例代码:

################################app.py############################
from flask import Flask, request, jsonify, render_template, redirect, url_for, session
from flask_session import Session
import mysql.connector

app = Flask(__name__)
app.secret_key = 'root'  # 用于会话管理
app.config['SESSION_TYPE'] = 'filesystem'  # 使用文件系统存储会话
Session(app)

# 预定义账号和密码
USERS = {
    'admin': 'admin',
    '旅馆管理系统': '123456'
}

# 数据库连接配置
db_config = {
    'host': 'localhost',
    'user': '旅馆管理系统',
    'password': '123456'
}

def get_db_connection():
    conn = mysql.connector.connect(
        host=db_config['host'],
        user=db_config['user'],
        password=db_config['password']
    )
    return conn

def get_databases():
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute("SHOW DATABASES")
    databases = [database[0] for database in cursor.fetchall() if database[0] != 'information_schema']  # 排除系统数据库
    cursor.close()
    conn.close()
    return databases

def get_tables(database):
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute(f"USE {database}")
    cursor.execute("SHOW TABLES")
    tables = [table[0] for table in cursor.fetchall()]
    cursor.close()
    conn.close()
    return tables

def get_table_fields(database, table):
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute(f"USE {database}")
    cursor.execute(f"SHOW COLUMNS FROM {table}")
    fields = [field[0] for field in cursor.fetchall()]
    cursor.close()
    conn.close()
    return fields

def get_table_records(database, table):
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute(f"USE {database}")
    cursor.execute(f"SELECT * FROM {table}")
    records = cursor.fetchall()
    cursor.close()
    conn.close()
    return records

# 获取表的主键字段
def get_table_primary_key(database, table):
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute(f"USE {database}")
    cursor.execute(f"SHOW KEYS FROM {table} WHERE Key_name = 'PRIMARY'")
    primary_key = cursor.fetchone()
    cursor.close()
    conn.close()
    return primary_key[4] if primary_key else None

# 用户登录页
@app.route('/', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        if username in USERS and USERS[username] == password:
            session['username'] = username  # 将用户名存储在session中
            return redirect(url_for('home'))
        else:
            return 'Invalid username or password', 401
    
    return render_template('login.html')

# 用户登出页
@app.route('/logout')
def logout():
    session.pop('username', None)  # 清除会话数据
    return redirect(url_for('login'))

# 用户管理页
@app.route('/home')
def home():
    if 'username' not in session:
        return redirect(url_for('login'))
    return render_template('index.html', databases=get_databases())

# 进入数据库
@app.route('/enter-database', methods=['POST'])
def enter_database():
    if 'username' not in session:
        return redirect(url_for('login'))

    selected_database = request.form.get('database')
    session['selected_database'] = selected_database
    return redirect(url_for('database_home'))

# 数据库主页
@app.route('/database_home')
def database_home():
    if 'username' not in session or 'selected_database' not in session:
        return redirect(url_for('login'))

    selected_database = session['selected_database']
    tables = get_tables(selected_database)
    selected_table = request.args.get('table', tables[0] if tables else None)
    fields = get_table_fields(selected_database, selected_table) if selected_table else []
    records = get_table_records(selected_database, selected_table) if selected_table else []
    primary_key = get_table_primary_key(selected_database, selected_table)

    return render_template('database_home.html', 
                           database=selected_database, 
                           tables=tables, 
                           selected_table=selected_table, 
                           fields=fields,
                           records=records,
                           field_names=fields,
                           primary_key=primary_key)  # 将主键字段传递给模板

# 获取表的字段
@app.route('/get_table_fields', methods=['POST'])
def get_table_fields_route():
    if 'username' not in session or 'selected_database' not in session:
        return redirect(url_for('login'))

    database = session['selected_database']
    table = request.form.get('table')
    fields = get_table_fields(database, table)
    return jsonify(fields)

# 保存记录
@app.route('/save_record', methods=['POST'])
def save_record():
    if 'username' not in session or 'selected_database' not in session:
        return jsonify({'success': False, 'error': 'Unauthorized'}), 403

    data = request.get_json()
    database = data['database']
    table = data['table']
    record = data['record']

    print("Saving record:", record)  # 添加调试输出

    if 'id' not in record:
        return jsonify({'success': False, 'error': 'Missing id'}), 400

    conn = get_db_connection()
    cursor = conn.cursor()

    update_query = f"UPDATE {database}.{table} SET "
    update_query += ", ".join([f"{field} = %s" for field in record.keys() if field != 'id'])
    update_query += " WHERE id = %s"
    params = [record[field] for field in record.keys() if field != 'id'] + [record['id']]

    try:
        cursor.execute(update_query, params)
        conn.commit()
        success = True
    except Exception as e:
        print(e)
        success = False

    cursor.close()
    conn.close()

    return jsonify({'success': success})

# 删除记录
@app.route('/delete_record', methods=['POST'])
def delete_record():
    if 'username' not in session or 'selected_database' not in session:
        return jsonify({'success': False, 'error': 'Unauthorized'}), 403

    data = request.get_json()
    database = data['database']
    table = data['table']
    record_name = data['name']  # 修改为 'name' 字段

    print("Deleting record with name:", record_name)  # 添加调试输出

    conn = get_db_connection()
    cursor = conn.cursor()

    delete_query = f"DELETE FROM {database}.{table} WHERE Name = %s"  # 使用 'Name' 字段作为唯一标识

    try:
        cursor.execute(delete_query, (record_name,))
        conn.commit()
        success = True
    except Exception as e:
        print(e)
        success = False

    cursor.close()
    conn.close()

    return jsonify({'success': success})

# 保存新记录
@app.route('/save_new_record', methods=['POST'])
def save_new_record():
    if 'username' not in session or 'selected_database' not in session:
        return jsonify({'success': False, 'error': 'Unauthorized'}), 403

    data = request.get_json()
    database = data['database']
    table = data['table']
    record = data['record']

    print("Saving new record:", record)  # 添加调试输出

    # 构造插入记录的 SQL 查询语句
    insert_query = f"INSERT INTO {database}.{table} ({', '.join(record.keys())}) VALUES ({', '.join(['%s']*len(record))})"
    params = tuple(record.values())  # 将记录的值转换为元组形式

    conn = get_db_connection()
    cursor = conn.cursor()

    try:
        cursor.execute(insert_query, params)
        conn.commit()
        success = True
    except Exception as e:
        print(e)
        success = False

    cursor.close()
    conn.close()

    return jsonify({'success': success})

# 执行搜索并返回结果
def search_records(database, table, keyword):
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    # 构造模糊搜索的 SQL 查询语句
    search_query = f"SELECT * FROM {database}.{table} WHERE "
    search_query += " OR ".join([f"{field} LIKE %s" for field in get_table_fields(database, table)])
    params = ['%' + keyword + '%'] * len(get_table_fields(database, table))

    cursor.execute(search_query, params)
    records = cursor.fetchall()

    cursor.close()
    conn.close()

    return records

# 搜索页面
@app.route('/search_results')
def search_results():
    if 'username' not in session or 'selected_database' not in session:
        return redirect(url_for('login'))

    selected_database = session['selected_database']
    selected_table = request.args.get('table')
    keyword = request.args.get('keyword')

    records = search_records(selected_database, selected_table, keyword)
    fields = get_table_fields(selected_database, selected_table)

    return render_template('search_results.html',
                           keyword=keyword,
                           database=selected_database,
                           selected_table=selected_table,
                           fields=fields,
                           records=records)

if __name__ == '__main__':
    app.run(debug=True)

以下是一些示例html

####################database_home.html#########################
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Database Home</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
            background-image: url('/static/background.jpg');
            background-size: cover;
            background-position: center;
            background-attachment: fixed;
            height: 100vh;
            overflow: auto;
        }

        .container {
            background-color: rgba(255, 255, 255, 0.8);
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
            margin: 20px;
        }

        h2 {
            margin-bottom: 10px;
            font-size: 24px;
        }

        button {
            padding: 12px 24px;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            font-size: 18px;
            outline: none;
            transition: background-color 0.3s ease;
        }

        .go-back-button {
            background-color: #dc3545;
            color: #fff;
            margin-bottom: 20px;
            text-align: right;
            font-size: 18px;
        }

        .go-back-button:hover {
            background-color: #c82333;
            text-align: right;
        }

        .search-form-container,
        .table-select-container {
            text-align: left;
            margin-bottom: 50px;
        }

        input[type="text"],
        select {
            width: calc(100% - 120px);
            padding: 10px;
            margin-bottom: 10px;
            box-sizing: border-box;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #f8f8f8;
            font-size: 18px;
            outline: none;
        }

        button[type="submit"] {
            padding: 12px 24px;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            background-color: #007bff;
            color: #fff;
            font-size: 18px;
            outline: none;
            transition: background-color 0.3s ease;
        }

        button[type="submit"]:hover {
            background-color: #0056b3;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 10px;
        }

        th,
        td {
            border: 1px solid black;
            padding: 8px;
            text-align: left;
        }

        th {
            background-color: #f2f2f2;
        }

        .editable {
            background-color: #e8f0fe;
        }

        #new-record-table {
            display: none;
            margin-top: 20px;
        }

        #new-record-table td {
            width: 150px;
            padding: 5px;
        }

        .icon-button {
            background: none;
            border: none;
            cursor: pointer;
            padding: 0;
            outline: none;
        }

        .icon-button img {
            width: 48px;
            /* 调整SVG图标的尺寸 */
            height: 48px;
            /* 调整SVG图标的尺寸 */
        }

        .divider {
            border-top: 2px solid #ccc;
            margin-top: 20px;
            margin-bottom: 20px;
        }

        .footer {
            position: fixed;
            bottom: 0;
            width: 100%;
            background-color: #d6dce1;
            padding: 10px 0;
            text-align: center;
            font-size: 14px;
            color: #6c757d;
        }
    </style>
</head>

<body>
    <div class="footer">
        Version 1.0.0
    </div>

    <div id="user-info"
        style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
        <span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
    </div>

    <div class="container">
        <h2 style="font-size: 50px; font-weight: bold;">当前数据库:{{ database }}</h2>
        <button class="go-back-button" style="float: right; background-color:#d05d63;"
            onclick="goBack()">退出当前数据库</button>
        <div class="search-form-container">
            <form id="search-form" onsubmit="search(event)">
                <input type="text" id="keyword" name="keyword" placeholder="搜索..."
                    style="height=45px; padding: 10px; border: 2px solid #ccc; border-radius: 10px; font-size: 16px;">
                <input type="hidden" name="table" value="{{ selected_table }}">
                <button type="submit" style="background-color:#a099dd;">搜索</button>
            </form>
        </div>

        <div class="table-select-container" style="display: flex; align-items: center; margin-top: 20px;">
            <label for="table-select" style="font-size: 20px; margin-right: 10px;"><strong>当前访问的表:</strong></label>
            <select id="table-select" name="table" onchange="updateTable(this.value)"
                style="font-size: 20px; width: 200px;">
                {% for table in tables %}
                <option value="{{ table }}" {% if table==selected_table %}selected{% endif %}>{{ table }}</option>
                {% endfor %}
            </select>
        </div>

        <button class="icon-button" onclick="toggleNewRecordForm()" style="text-align: center;">
            <img src="/static/svg/档案.svg" alt="添加记录" style="vertical-align: middle;">
            <br>
            <span id="toggle-text" style="font-size: 20px; font-weight: bold;">{{ '添加记录明细' if button_new_record_activate
                else '添加记录' }}</span>
        </button>

        <div id="new-record-table">
            <h3>添加记录</h3>
            <table id="new-record-form">
                <tbody>
                    {% for field in field_names %}
                    <tr>
                        <td>{{ '*' if field == primary_key else '' }}{{ field }}</td>
                        <td><input type="text" id="new-{{ field }}" name="{{ field }}"></td>
                    </tr>
                    {% endfor %}
                    <tr>
                        <td colspan="2" style="text-align: center;"><button class="icon-button"
                                onclick="saveNewRecord()"><img src="/static/svg/上传.svg" alt="保存"></button></td>
                    </tr>
                </tbody>
            </table>
        </div>

        <div class="divider"></div>

        <h3>记录列表</h3>
        <table id="record-list">
            <thead>
                <tr>
                    {% for field in fields %}
                    <th>{{ field }}</th>
                    {% endfor %}
                    <th>保存修改</th>
                    <th>删除</th>
                </tr>
            </thead>
            <tbody>
                {% for record in records %}
                <tr>
                    {% for field in fields %}
                    <td contenteditable="true" data-field="{{ field }}">{{ record[field] }}</td>
                    {% endfor %}
                    <td><button class="icon-button" onclick="saveRecord(this)"><img src="/static/svg/编辑.svg"
                                alt="保存"></button></td>
                    <td><button class="icon-button" onclick="confirmDelete(this)"><img src="/static/svg/删除.svg"
                                alt="删除"></button></td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>

    <script>
        let button_new_record_activate = false;

        function toggleNewRecordForm() {
            button_new_record_activate = !button_new_record_activate;
            document.getElementById('new-record-table').style.display = button_new_record_activate ? 'block' : 'none';
        }

        function updateTable(table) {
            const urlParams = new URLSearchParams(window.location.search);
            urlParams.set('table', table);
            window.location.search = urlParams.toString();
        }

        function saveRecord(button) {
            const row = button.closest('tr');
            const fields = {};
            row.querySelectorAll('td[data-field]').forEach(td => {
                const fieldName = td.getAttribute('data-field');
                fields[fieldName.toLowerCase()] = td.innerText;
            });

            fetch('/save_record', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    database: '{{ database }}',
                    table: '{{ selected_table }}',
                    record: fields
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('记录保存成功');
                    } else {
                        alert('记录保存失败');
                    }
                });
        }

        function confirmDelete(button) {
            if (confirm("确定要删除吗?")) {
                deleteRecord(button);
            } else {
                // 用户取消删除操作
            }
        }

        function deleteRecord(button) {
            const row = button.closest('tr');
            const recordName = row.querySelector('td[data-field="Name"]').innerText;

            fetch('/delete_record', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    database: '{{ database }}',
                    table: '{{ selected_table }}',
                    name: recordName
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('记录删除成功');
                        row.remove();
                    } else {
                        alert('记录删除失败');
                    }
                });
        }

        function search(event) {
            event.preventDefault();

            const keyword = document.getElementById('keyword').value.trim();
            if (keyword === '') {
                alert('请输入搜索关键字');
                return;
            }

            const formData = new FormData(document.getElementById('search-form'));
            const searchParams = new URLSearchParams(formData).toString();
            window.location.href = `/search_results?${searchParams}`;
        }

        function showNewRecordForm() {
            document.getElementById('new-record-table').style.display = 'block';
        }

        function saveNewRecord() {
            const record = {};
            {% for field in field_names %}
            record['{{ field }}'] = document.getElementById('new-{{ field }}').value;
            {% endfor %}

            fetch('/save_new_record', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    database: '{{ database }}',
                    table: '{{ selected_table }}',
                    record: record
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('数据保存成功');
                        window.location.href = `/database_home?table={{ selected_table }}`;
                    } else {
                        alert('数据保存失败,请检查填写的数据格式或关键字错误');
                    }
                });
        }

        function goBack() {
            window.location.href = '/home';
        }

        function toggleNewRecordForm() {
            button_new_record_activate = !button_new_record_activate;
            document.getElementById('new-record-table').style.display = button_new_record_activate ? 'block' : 'none';
            document.getElementById('toggle-text').innerText = button_new_record_activate ? '收起添加记录明细' : '添加记录';
        }

    </script>
</body>

</html>
##############################index.html#################################
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据库选择</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-image: url('/static/background.jpg');
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
        }

        .container {
            background-color: rgba(255, 255, 255, 0.8);
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
            margin: 20px;
            width: 50%;
            /* 设置容器的宽度为页面宽度的 80% */
        }

        form {
            display: inline-block;
            text-align: left;
            width: 100%;
        }

        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }

        input[type="text"],
        input[type="password"],
        select {
            width: 100%;
            padding: 10px;
            margin-bottom: 20px;
            box-sizing: border-box;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #f8f8f8;
            font-size: 16px;
            outline: none;
        }

        .button-container {
            display: flex;
            justify-content: space-between;
        }

        button[type="submit"],
        .logout-button {
            padding: 10px 40px;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            font-size: 16px;
            outline: none;
            transition: background-color 0.3s ease;
            width: 48%;
            /* 设置按钮宽度为48% */
            text-align: center;
        }

        button[type="submit"] {
            background-color: #007bff;
            color: #fff;
        }

        button[type="submit"]:hover {
            background-color: #0056b3;
        }

        .logout-button {
            background-color: #dc3545;
            color: #fff;
            text-decoration: none;
            display: inline-block;
            line-height: 1.5;
        }

        .logout-button:hover {
            background-color: #c82333;
        }

        h2 {
            margin-bottom: 10px;
            color: white;
        }

        h4 {
            margin-bottom: 20px;
            font-size: 14px;
            text-align: right;
            color: white;
        }

        .footer {
            position: fixed;
            bottom: 0;
            width: 100%;
            background-color: #d5dee7;
            padding: 10px 0;
            text-align: center;
            font-size: 14px;
            color: #6c757d;
        }
    </style>
</head>

<body>
    <div id="user-info"
        style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
        <span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
    </div>

    <div class="container">
        <h2>数据库信息管理系统</h2>
        <h4>——buid by 𝓣𝔀𝓲𝓽𝓲𝓰𝓱𝓽@yhy2021_IEE</h4>

        <form action="/enter-database" method="post">
            <label for="db_user">数据库用户:</label>
            <input type="text" id="db_user" name="db_user" required>
            <label for="db_password">数据库密码:</label>
            <input type="password" id="db_password" name="db_password" required>
            <label for="database">选择数据库:</label>
            <select id="database" name="database">
#############模拟权限管理,这一版已经被淘汰了,这个写法不好################
                {% if session['username'] == '旅馆管理系统' %}
                <option value="world">world</option>
                <option value="test_db">test_db</option>
                {% else %}
                {% for database in databases %}
                <option value="{{ database }}">{{ database }}</option>
                {% endfor %}
                {% endif %}
            </select>
            <div class="button-container">
                <a href="/" class="logout-button">退出登录</a>
                <button type="submit">进入数据库</button>
            </div>
        </form>
    </div>

    <div class="footer">
        Version 1.0.0
    </div>

</body>

</html>
#################################login.html#################################
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-image: url('/static/background.jpg');
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
        }

        .login-container {
            text-align: center;
            position: relative;
            border-radius: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
            width: 400px;
        }

        .gif-background {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 120%;
            height: 150%;
            background-image: url('/static/img.gif');
            background-size: cover;
            /* 自适应拉伸 */
            border-radius: 20px;
            z-index: -1;
        }

        h2 {
            color: white;
        }

        form {
            display: inline-block;
            text-align: left;
            position: relative;
            z-index: 1;
        }

        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: white;
        }

        input[type="text"],
        input[type="password"] {
            width: 100%;
            padding: 10px;
            margin-bottom: 20px;
            box-sizing: border-box;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #f8f8f8;
            font-size: 16px;
            color: white;
            outline: none;
        }

        button[type="submit"] {
            padding: 10px 100px;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            background-color: #007bff;
            color: #fff;
            font-size: 16px;
            outline: none;
            transition: background-color 0.3s ease;
        }

        button[type="submit"]:hover {
            background-color: #0056b3;
        }
    </style>
</head>

<body>
    <div class="login-container">
        <div class="gif-background"></div>
        <h2>MySQL信息管理系统统一登录</h2>
        <form method="post">
            <label for="username">信息管理系统账户:</label>
            <input type="text" id="username" name="username" required><br><br>
            <label for="password">密码:</label>
            <input type="password" id="password" name="password" required><br><br>
            <button type="submit">登录</button>
        </form>
    </div>
</body>

</html>
#################################search_results.html#############################

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Search Results</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-image: url('/static/background.jpg');
            background-size: cover;
            background-position: center;
            height: 100vh;
            overflow: auto;
        }

        .container {
            background-color: rgba(255, 255, 255, 0.8);
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
            margin: 20px;
        }

        h1 {
            margin-top: 0;
        }

        button {
            padding: 10px 20px;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            font-size: 16px;
            outline: none;
            transition: background-color 0.3s ease;
        }

        button:hover {
            background-color: #0056b3;
            color: #fff;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }

        th,
        td {
            border: 1px solid #ccc;
            padding: 8px;
            text-align: left;
        }

        th {
            background-color: #f2f2f2;
        }

        .editable {
            background-color: #e8f0fe;
        }
    </style>
</head>

<body>
    <div id="user-info"
        style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
        <span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
    </div>

    <div class="container">
        <h1>搜索条件 <button class="go-back-button" style="float: right; background-color:#d05d63;"
                onclick="goBack()">返回上一级</button></h1>
        <p style="font-size: 18px; font-weight: bold;">搜索关键词: {{ keyword }}</p>
        <p style="font-size: 18px; font-weight: bold;">被搜索数据库: {{ database }}</p>
        <p style="font-size: 18px; font-weight: bold;">被搜索表: {{ selected_table }}</p>
        <form id="search-form" style="text-align: left;" onsubmit="search(event)">
            <input type="text" id="keyword" name="keyword" placeholder="搜索..."
                style="width: 50%; padding: 10px; border: 2px solid #ccc; border-radius: 10px; font-size: 16px;">
            <input type="hidden" name="table" value="{{ selected_table }}">
            <button type="submit" style="background-color:#a099dd;">搜索</button>
        </form>

        <h2>搜索结果列表:</h2>
        <table>
            <thead>
                <tr>
                    {% for field in fields %}
                    <th>{{ field }}</th>
                    {% endfor %}
                    <th>修改</th>
                    <th>删除</th>
                </tr>
            </thead>
            <tbody>
                {% for record in records %}
                <tr>
                    {% for field in fields %}
                    <td contenteditable="true" data-field="{{ field }}">{{ record[field] }}</td>
                    {% endfor %}
                    <td><button onclick="saveRecord(this)">保存</button></td>
                    <td><button onclick="confirmDelete(this, '{{ record.Name }}')">删除</button></td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>

    <script>
        function goBack() {
            window.history.back(); // 返回到上一个页面,即database_home.html页面
        }

        function search(event) {
            event.preventDefault(); // 阻止表单默认提交行为

            const keyword = document.getElementById('keyword').value.trim();
            if (keyword === '') {
                alert('请输入搜索关键字');
                return;
            }

            const formData = new FormData(document.getElementById('search-form'));
            const searchParams = new URLSearchParams(formData).toString();
            window.location.href = `/search_results?${searchParams}`;
        }

        function saveRecord(button) {
            const row = button.closest('tr');
            const fields = {};
            row.querySelectorAll('td[data-field]').forEach(td => {
                const fieldName = td.getAttribute('data-field');
                fields[fieldName.toLowerCase()] = td.innerText;
            });

            fetch('/save_record', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    database: '{{ database }}',
                    table: '{{ selected_table }}',
                    record: fields
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('记录保存成功');
                    } else {
                        alert('记录保存失败');
                    }
                });
        }

        function confirmDelete(button, name) {
            if (confirm("确定要删除吗?")) {
                deleteRecord(button, name);
            } else {
                // 用户取消删除操作
            }
        }

        function deleteRecord(button, name) {
            const row = button.closest('tr');

            fetch('/delete_record', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    database: '{{ database }}',
                    table: '{{ selected_table }}',
                    name: name // 将记录的名称作为参数传递
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('记录删除成功');
                        row.remove();
                    } else {
                        alert('记录删除失败');
                    }
                });
        }
    </script>
</body>

</html>

注,需要把html放到名为templates的文件夹下。

That’s All,THANKS!

标签: flask mysql python

本文转载自: https://blog.csdn.net/qq_73407651/article/details/139700129
版权归原作者 能不能不要报错! 所有, 如有侵权,请联系我们删除。

“使用python的flask框架做一个本地mysql服务器的webui!”的评论:

还没有评论