当前位置: 首页 > article >正文

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

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

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

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

新增功能

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

1. 数据库管理(SqlLite)

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

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

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

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全代码,此处只展示修改的信息

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 此处一样只展示心增代码

class WinGUI(Tk):
    def __init__(self):
        super().__init__()
		self.user: json = {}
		
	def set_user(self, user: json):
        self.user = user

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


http://www.kler.cn/news/323750.html

相关文章:

  • 【WPF】多屏幕展示
  • Flask学习之项目搭建
  • Linux上的C/C++编程
  • 【管理】销售管理到底应该怎么管?
  • uniapp 实现3d轮播图,也就是中间的放大两边的缩小 用swiper和swiper-item就能实现
  • CentOS7 离线部署docker和docker-compose环境
  • 图说数集相等定义表明“R各元x的对应x+0.0001的全体=R“是几百年重大错误
  • c++与Python用笛卡尔的心形函数输出爱心
  • 学习ubuntu 24.10系统目录架构
  • 【Qt】前后端交互---DataCenter类
  • 牛顿迭代法求解x 的平方根
  • 架构师:消息队列的技术指南
  • Unity 网格的细节级别 (LOD) 学习
  • Python Web架构:微服务与服务网格的实践
  • C. Cards Partition 【Codeforces Round 975 (Div. 2)】
  • 强化-极限
  • Netty入门
  • 机器学习(4):机器学习项目步骤(一)——定义问题
  • Pytorch实现Transformer
  • 激光slam学习笔记4--slam_in_autonomous_driving编译碰到问题汇总
  • 基于Python+flask+MySQL+HTML的全国范围水质分析预测系统,可视化用echarts,预测算法随机森林
  • [Redis][Zset]详细讲解
  • FastAPI前置知识及快速入门
  • Python入门:类的异步资源管理与回收( __del__ 方法中如何调用异步函数)
  • CMake构建学习笔记18-cpp-httplib库的构建
  • 【目标检测】隐翅虫数据集386张VOC+YOLO
  • 【web阅读记录】web相关概念及知识整理
  • 【机器学习】——支持向量机
  • uni-app 封装websocket 心跳检测,开箱即用
  • SCAU学习笔记 - 面向对象程序设计课后习题