Tkinter制作登录界面以及登陆后页面切换--用户数据从数据库获取并进行合法性校验(二)

Tkinter制作登录界面以及登陆后页面切换(二)

  • 新增功能
    • [1. 数据库管理(SqlLite)](#1. 数据库管理(SqlLite))
    • [2. 用户表创建(用户信息增删改查操作)](#2. 用户表创建(用户信息增删改查操作))
    • [3. 完善登录校验](#3. 完善登录校验)

续接上集,废话不多说,开搞!

新增功能

  1. 数据库管理
  2. 用户表创建(用户信息增删改查操作)
  3. 完善登录校验

1. 数据库管理(SqlLite)

下面代码中 from data import Sql, BcryptUtils 引入的是自己写的包,Sql用来记录需要初始化的信息(创建基础表,添加管理用户等), BcryptUtils 主要是对密码进行加密哈希和校验密码是否正确

python 复制代码
import json
import sqlite3

from data import Sql, BcryptUtils


class SqlUtils:
    def __init__(self):
        # 不再在初始化时直接建立连接,而是在需要时建立
        self.database_name = 'platform.db'

    def init(self):
        """ 初始化数据库 """
        # 创建基础数据表和初始化表单数据时建立连接并在完成后关闭
        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            for sql in Sql.create_sqls:
                cursor.execute(sql)
            for sql in Sql.insert_sqls:
                cursor.execute(sql)
            conn.commit()

    def query(self, sql):
        """
        查询数据,返回格式:{'字段名':'数值'}
        :param sql: 需要查询的sql
        :return: 返回查询到的数据,没有数据时返回None
        """
        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            cursor.execute(sql)
            _rows = cursor.fetchall()
            columns = [description[0] for description in cursor.description]
            return [dict(zip(columns, _row)) for _row in _rows]

    def insert(self, sql: str):
        """
        插入数据方法
        :param sql: 插入数据的sql
        :return: 成功返回True,否则False
        """
        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            cursor.execute(sql)
            conn.commit()
            rows_affected = cursor.rowcount
            return rows_affected > 0

    def insert_json(self, table_name: str, data_dict: json) -> object:
        # 解析 JSON 获取键值对
        columns = ', '.join(data_dict.keys())
        placeholders = ', '.join(['?'] * len(data_dict))
        values = tuple(data_dict.values())

        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            # 拼接 SQL 语句
            sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
            try:
                cursor.execute(sql, values)
                conn.commit()
                return True
            except Exception as e:
                print(f"插入失败:{e}")
                conn.rollback()
                return False

    def delete(self, table_name: str, data_dict: json):
        if not data_dict or len(data_dict) == 0:
            return False, "条件为空,不允许删除。"
        conditions = []
        values = []
        for key, value in data_dict.items():
            conditions.append(f"{key}=?")
            values.append(value)
        sql = f"DELETE FROM {table_name} WHERE {' AND '.join(conditions)}"
        with sqlite3.connect(self.database_name) as conn:
            try:
                cursor = conn.cursor()
                cursor.execute(sql, values)
                conn.commit()
                rows_affected = cursor.rowcount
                return rows_affected > 0
            except Exception as e:
                print(f"删除失败:{e}")
                conn.rollback()
                return False

    def login_user(self, username, password):
        """
        用户登录判断接口,返回True代表允许登录
        :param username: 用户账号
        :param password: 用户密码
        :return: 成功返回True,用户数据,失败则返回False,原因
        """
        user_data = self.query(f"SELECT * FROM sys_user WHERE username='{username}'")
        if user_data:
            row = user_data[0]
            if BcryptUtils.check_password(password, row['password']):
                return True, row
            else:
                return False, '账号或密码错误'
        else:
            return False, "没有当前登录的账号信息。"


if __name__ == '__main__':
    sql_utils = SqlUtils()
    sql_utils.init()
    sql_utils.insert_json("sys_user", {
        "name": "测试", "username": "admin",
        "password": BcryptUtils.hash_password('123456')
    })
    input_username = "admin"
    input_password = "123456"
    res, data = sql_utils.login_user(input_username, input_password)
    if res is True:
        extend_str = data.get('extend')
        extend_dict = json.loads(extend_str) if extend_str else {}
        print(f"欢迎您,{data.get('name')},您的账号是:{data.get('username')},头像:{extend_dict.get('img')}")
    else:
        print(f'{data}')
    # 删除用户
    sql_utils.delete("sys_user", {
        "username": "admin"
    })

2. 用户表创建(用户信息增删改查操作)

data/Sql.py

python 复制代码
create_sqls = []

create_drop_user = "DROP TABLE IF EXISTS sys_user;"
create_sqls.append(create_drop_user)

create_user = '''
        CREATE TABLE IF NOT EXISTS sys_user
        (
            id        INTEGER PRIMARY KEY,
            name      varchar(255)       not null,
            username  varchar(32)        not null,
            password  varchar(255)       not null,
            is_active blob default false not null,
            extend    json,
            unique (username)
        );
        '''
create_sqls.append(create_user)

insert_sqls = []

insert_user = """
insert into sys_user(name, username, password, extend)
        values ('超级管理员', 'admin', 
        '$2b$12$v/PNEi9kMoAafg17SneZ8eiX2/CC/BGWjCI4l.ynkfLcRhXm4TPdW', 
        '{"img":"http:127.0.0.1/statics/super/image/super.png"}');
"""
insert_sqls.append(insert_user)

3. 完善登录校验

data/BcryptUtils.py ,引入依赖命令: pip install bcrypt

python 复制代码
import bcrypt


def check_password(plain_password, hashed_password):
    """
    验证密码
    :param plain_password: 明文密码
    :param hashed_password: 哈希密码
    :return: 匹配则返回True,否则返回False
    """
    plain_password = plain_password.encode('utf-8')
    hashed_password = hashed_password.encode('utf-8')
    return bcrypt.checkpw(plain_password, hashed_password)


def hash_password(password):
    """
    对密码进行加密
    :param password: 用户密码
    :return: 返回加密的密文
    """
    password = password.encode('utf-8')
    hashed = bcrypt.hashpw(password, bcrypt.gensalt())
    return hashed.decode('utf-8')

login/ui.py 不清楚这个去看一下一中的ui.py全代码,此处只展示修改的信息

python 复制代码
from data.SqlLiteUtils import SqlUtils


class Controller:
    # 导入UI类后,替换以下的 object 类型,将获得 IDE 属性提示功能
    ui: WinGUI

    def __init__(self):
        ....保持原有代码....下方是新增代码
        self.sql_utils = SqlUtils()
    
    def login_submit(self, evt):
        u, p = self.ui.login()
        if u is None or len(u) == 0:
            tkinter.messagebox.showinfo("登录提示", "请输入登录用户名!")
        elif p is None or len(p) == 0:
            tkinter.messagebox.showinfo("登录提示", "请输入登录密码!")
        print(
            f"触发了登录操作,地址:{self.url},账号:{u},密码:{p}")
        res, user = self.sql_utils.login_user(u, p)
        if res is True:
            print(f"欢迎您,{user.get('name')}")
            self.ui.destroy()
            from home.control import Controller as HomeUIController
            from home.ui import Win as MainWin
            app = MainWin(HomeUIController())
            app.set_user(user)
            app.mainloop()
        else:
            tkinter.messagebox.showinfo("登录提示", user)

home/ui.py 此处一样只展示心增代码

python 复制代码
class WinGUI(Tk):
    def __init__(self):
        super().__init__()
		self.user: json = {}
		
	def set_user(self, user: json):
        self.user = user

好了,到这里结束了,后续会开始做注册用户操作,需要整体源代码的可以留言或SL俺!

相关推荐
极光代码工作室9 小时前
基于NLP的电商评论情感分析系统
python·深度学习·自然语言处理·情感分析·文本挖掘
csdn2015_9 小时前
List<DocumentMetadata> 取所有docid,组成List<String>
windows·python·list
清水白石0089 小时前
《Python 静态检查链:格式化、Lint、类型检查、安全扫描全攻略——CI 阻断策略与团队平衡实践》
python·安全·ci/cd
soragui9 小时前
【Python】第 2 章:Python 对象模型
开发语言·python
高洁0110 小时前
大模型Prompt实战:精准生成专业技术文档
人工智能·python·数据挖掘·transformer·知识图谱
努力学习的小廉10 小时前
Python 零基础入门——基础语法(一)
java·网络·python
源码之家10 小时前
计算机毕业设计:Python二手车数据分析推荐系统 Flask框架 requests爬虫 协同过滤推荐算法 可视化 汽车之家 机器学习(建议收藏)✅
大数据·python·机器学习·数据分析·flask·汽车·课程设计
章鱼丸-10 小时前
DAY43
python
zero159710 小时前
Python 8天极速入门笔记(大模型工程师专用):第七篇-文件操作 + 异常处理,大模型实战落地关键
python·ai编程·大模型编程语言
T0uken10 小时前
【Python】uvpacker:跨平台打包 Windows 应用
开发语言·python