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俺!

相关推荐
xywww1682 小时前
大模型 API 选型实战:GPT、Gemini、Claude 接入时该看哪些指标?
运维·服务器·人工智能·python·gpt·langchain
夜雪一千7 小时前
Python enumerate() 函数完整详解:遍历同时获取索引,告别手动计数
服务器·windows·python
能有时光7 小时前
PyTorch KernelAgent 源码解读 ---(4)--- ExtractorAgent
人工智能·pytorch·python
_Jimmy_8 小时前
Python 协程库如何使用以及有哪些使用场景
python
aqi008 小时前
15天学会AI应用开发(十七)使用LangGraph实现会话记忆功能
人工智能·python·大模型·ai编程·ai应用
第一程序员8 小时前
Rust Agent 子进程执行:Command 之前,先定义输入和超时
python·rust·github
skywalk81638 小时前
设计并实现段言的 C FFI 绑定机制 @Trae
c语言·开发语言·python·编程
weixin_BYSJ19879 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
EQUINOX110 小时前
【论文阅读】| MoCo精读
论文阅读·人工智能·python·深度学习·机器学习
用户83562907805111 小时前
使用 Python 自动化 Excel 公式和函数:完整指南
后端·python