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

相关推荐
V_fanglue370516 分钟前
qmt量化交易策略小白学习笔记第67期【qmt编程之获取ETF申赎清单】
大数据·前端·数据库·笔记·python·学习·区块链
FreakStudio22 分钟前
全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码
python·嵌入式·面向对象·电子diy
软糖工程0011 小时前
正则表达式【详细解读】
大数据·前端·爬虫·python·学习·正则表达式·数据分析
程序员的战歌1 小时前
django drf to_internal_value
python·django
程序员的战歌1 小时前
django drf 分页器
python·django
第六五2 小时前
__init__.py文件
python
EelBarb2 小时前
python:基于django的html二维码页面生成功能页面
python·django·html
Rverdoser2 小时前
macOS 系统中python的安装步骤
开发语言·python·macos
亮剑20182 小时前
文科生学pytorch——一些概念的解释
人工智能·pytorch·python
爱技术的小伙子3 小时前
【30天玩转python】网络爬虫开发
开发语言·爬虫·python