Python實(shí)現(xiàn)的登錄驗(yàn)證系統(tǒng)完整案例【基于搭建的MVC框架】
本文實(shí)例講述了Python實(shí)現(xiàn)的登錄驗(yàn)證系統(tǒng)。分享給大家供大家參考,具體如下:
小型登錄注冊(cè)驗(yàn)證系統(tǒng)
一、概述
使用Redis+MySQL數(shù)據(jù)庫(kù)實(shí)現(xiàn)一個(gè)小型的登錄注冊(cè)驗(yàn)證系統(tǒng)。在這個(gè)系統(tǒng)中初步了解認(rèn)識(shí)MVC框架。
具備功能:登錄、注冊(cè)、改密、注銷(xiāo)。
數(shù)據(jù)庫(kù):Redis,MySQL。使用Redis把用戶(hù)信息存儲(chǔ)在內(nèi)存中,查詢(xún)數(shù)據(jù)快。MySQL存儲(chǔ)空間更大,對(duì)表之間的關(guān)系管理更好。兩者結(jié)合使用發(fā)揮各自的優(yōu)勢(shì)已是當(dāng)下流行的數(shù)據(jù)庫(kù)使用方式。
開(kāi)發(fā)語(yǔ)言:Python。
MVC框架:MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫(xiě),一種軟件設(shè)計(jì)典范,用一種業(yè)務(wù)邏輯、數(shù)據(jù)、界面顯示分離的方法組織代碼,將業(yè)務(wù)邏輯聚集到一個(gè)部件里面,在改進(jìn)和個(gè)性化定制界面及用戶(hù)交互的同時(shí),不需要重新編寫(xiě)業(yè)務(wù)邏輯。MVC被獨(dú)特的發(fā)展起來(lái)用于映射傳統(tǒng)的輸入、處理和輸出功能在一個(gè)邏輯的圖形化用戶(hù)界面的結(jié)構(gòu)中。
二、代碼
完整實(shí)例代碼點(diǎn)擊此處本站下載。
GitHub地址:https://github.com/liangdongchang/pyCheckLoginSys.git
1、Init
用來(lái)初始化服務(wù):
①、在mysql上新建一個(gè)數(shù)據(jù)庫(kù)“homework”和建表”t_usr”
②、開(kāi)啟redis服務(wù)程序
''' @author ldc ''' import os import pymysql ''' 初始化服務(wù): 1、在mysql上新建一個(gè)數(shù)據(jù)庫(kù)“homework”和建表"t_usr" 2、開(kāi)啟redis服務(wù)程序 ''' # 建立數(shù)據(jù)庫(kù)連接 conn = pymysql.connect( host='localhost', user='root', password="123456", port=3306 ) # 獲取游標(biāo) cursor = conn.cursor() # 創(chuàng)建數(shù)據(jù)庫(kù) dbname = 'homework' sql=''' create database if not EXISTS %s charset=utf8; '''%dbname cursor.execute(sql) # 使用數(shù)據(jù)庫(kù) cursor.execute('use %s'%dbname) # 創(chuàng)建表 sql = ''' create table if not EXISTS t_usr( id INTEGER PRIMARY KEY auto_increment, username varchar(20) unique not null, password varchar(20) not null ); ''' cursor.execute(sql) # 關(guān)閉游標(biāo)與連接 cursor.close() conn.close() # 開(kāi)啟redis服務(wù),新建一個(gè)啟動(dòng)redisd.bat文件, #以后開(kāi)啟redis服務(wù)就可以直接打開(kāi)這個(gè)文件了 def openRedisd(path): rPath = """@echo off redis-server %s pause"""%path with open(r"C:\Users\LDCPC\Desktop\啟動(dòng)redisd.bat","w",encoding="ANSI") as f: f.write(rPath) openRedisd(r"D:\ruanjian\redis-64.2.8.2101\redis.windows.conf") # 打開(kāi)文件“啟動(dòng)redisd.bat” os.popen(r"C:\Users\LDCPC\Desktop\啟動(dòng)redisd.bat")
2、View層
用來(lái)與用戶(hù)交互:接收用戶(hù)的輸入和顯示結(jié)果給用戶(hù)。
''' @author ldc ''' from controller import urls from model.model import User from utils.dbUtil import RedisUtil ''' 需求:登錄注冊(cè)驗(yàn)證 1、登錄 2、注冊(cè) 3、改密 4、注銷(xiāo) ''' # 主界面接口 def index(): while True: #登錄界面 print("********************************") print("* *") print("* (1) 登錄 (2)注冊(cè) *") print("* (3) 改密 (4)注銷(xiāo) *") print("* (5)退出 *") print("********************************") print() num = input("請(qǐng)輸入功能序號(hào):") if num in ['1','2','3','4','5']: return num else: print("輸入有誤,請(qǐng)重新輸入!!!") # 輸入賬號(hào)與密碼 def inputInfo(): return input("請(qǐng)輸入賬號(hào)和密碼(逗號(hào)隔開(kāi)):").split(',') if __name__ == '__main__': # 連接redis數(shù)據(jù)庫(kù) RedisUtil.connect() while True: # 初始化界面 num = index() # 輸入賬號(hào)密碼 username, password = inputInfo() # 實(shí)例化一個(gè)用戶(hù)類(lèi) user = User(username, password) if num == '1': urls.login(user) #登錄 elif num == '2': urls.regist(user) # 注冊(cè) elif num == '3': urls.changePasswd(user) # 改密 elif num == '4': urls.deleteUser(user) # 注銷(xiāo) else: break
3、Controller層
實(shí)現(xiàn)業(yè)務(wù)邏輯,控制整個(gè)系統(tǒng)的實(shí)現(xiàn)流程。
''' @author ldc ''' from model.model import UserDao # 先查詢(xún)?cè)撚脩?hù)是否存在數(shù)據(jù)庫(kù)中 def exists(user): '''先查看Redis緩存中是否有該用戶(hù)數(shù)據(jù)''' if not UserDao.exists(user.username, 'redis'): '''然后在mysql中查詢(xún)?cè)撚脩?hù)是否存在''' if UserDao.exists(user.username, 'mysql'): # 若在mysql存在就把該用戶(hù)寫(xiě)進(jìn)redis, UserDao.redis.set(user.username, user.password) return 'mysql' else : return None return 'redis' ''' # 登錄模塊 先在redis上驗(yàn)證,驗(yàn)證成功則提示在redis上驗(yàn)證成功 否則到mysql中驗(yàn)證,驗(yàn)證成功則提示在mysql上驗(yàn)證成功 否則提示用戶(hù)不存在 ''' def login(user): print("------------登錄界面------------") # 查詢(xún)?cè)撚脩?hù)信息是否存在數(shù)據(jù)庫(kù)中 whereDB = exists(user) if whereDB == 'redis': # 匹配密碼是否正確 if UserDao.query(user, 'redis') == user.password: print("[在redis中查詢(xún)到該用戶(hù)]登錄成功!!!") return 1 else: print("[在redis中查詢(xún)到該用戶(hù)] 登錄失敗,用戶(hù)名或者密碼不正確!!!") elif whereDB == 'mysql': # 匹配密碼是否正確 if UserDao.query(user, 'mysql'): print("[在mysql中查詢(xún)到該用戶(hù)] 登錄成功!!!") return 1 else: print("[在mysql中查詢(xún)到該用戶(hù)] 登錄失敗,用戶(hù)或者密碼不正確!!!") else: print("[在mysql中查詢(xún)不到該用戶(hù)]登錄失敗,該用戶(hù)不存在,請(qǐng)注冊(cè)后再登錄!!!") return 0 ''' # 注冊(cè)模塊 先在redis上查詢(xún)賬號(hào)是否存在,存在則注冊(cè)失敗 否則到mysql上查詢(xún),用戶(hù)存在則注冊(cè)失敗 否則注冊(cè)成功,把賬號(hào)寫(xiě)進(jìn)mysql,寫(xiě)進(jìn)redis ''' def regist(user): print("------------注冊(cè)界面------------") # 查詢(xún)?cè)撚脩?hù)信息是否存在數(shù)據(jù)庫(kù)中 whereDB = exists(user) if whereDB : print("注冊(cè)失敗,該用戶(hù)已存在!!!") else: if UserDao.insert(user): print("注冊(cè)成功!!!") else: print("注冊(cè)失敗!!!") ''' # 修改密碼模塊 先在redis上和mysql上查詢(xún),用戶(hù)存在就在mysql上修改該用戶(hù)密碼, 然后把該用戶(hù)信息重新寫(xiě)進(jìn)redis中 在mysql中查詢(xún)不到該用戶(hù),就返回該用戶(hù)不存在,改密失敗 ''' def changePasswd(user): print("------------改密界面------------") # 查詢(xún)?cè)撚脩?hù)信息是否存在數(shù)據(jù)庫(kù)中 whereDB = exists(user) if whereDB: user.password = input("請(qǐng)輸入新密碼:") if UserDao.changePasswd(user): print("改密成功!!!") else: print("改密失敗!!!") else: print("用戶(hù)不存在,改密失敗!!!") ''' # 注銷(xiāo)用戶(hù)模塊 先在在redis上和mysql上查詢(xún),用戶(hù)存在就在mysql和redis上刪除該用戶(hù) 在mysql中查詢(xún)不到該用戶(hù),就返回該用戶(hù)不存在,注銷(xiāo)失敗 ''' def deleteUser(user): print("------------注銷(xiāo)界面------------") # 查詢(xún)?cè)撚脩?hù)信息是否存在數(shù)據(jù)庫(kù)中 if login(user): if UserDao.deleteUser(user): print("注銷(xiāo)成功!!!") return print("注銷(xiāo)失敗!!!")
4、Model層
用來(lái)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),實(shí)現(xiàn)業(yè)務(wù)邏輯與數(shù)據(jù)庫(kù)分離,易于維護(hù)系統(tǒng)。
''' @author ldc ''' from utils.dbUtil import RedisUtil, MySQLUtil # 用戶(hù)模型類(lèi) class User: def __init__(self,username,password): self.username = username self.password = password # UserDao # 封裝了對(duì)User數(shù)據(jù)的增刪改查 # Dao=Database Access Object 數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)對(duì)象 class UserDao: # 創(chuàng)建數(shù)據(jù)庫(kù)對(duì)象 redis = RedisUtil() mySQL = MySQLUtil('homework','t_usr') # 執(zhí)行數(shù)據(jù)庫(kù)查詢(xún)操作,返回查詢(xún)結(jié)果 @classmethod def query(cls,user,dbType): dataDict = {} dataDict["username"] = user.username dataDict["password"] = user.password if dbType == 'redis': return cls.redis.get(user.username) elif dbType == 'mysql': return cls.mySQL.query(dataDict) # 執(zhí)行數(shù)據(jù)庫(kù)查詢(xún)操作,查詢(xún)用戶(hù)是否存在,返回查詢(xún)結(jié)果 @classmethod def exists(cls,username,dbType): dataDict = {} dataDict["username"] = username if dbType == 'redis': return cls.redis.exists(username) elif dbType == 'mysql': return cls.mySQL.exists(dataDict) else: pass # 執(zhí)行數(shù)據(jù)插入操作,先把用戶(hù)信息添加進(jìn)mysql,然后再添加進(jìn)redis @classmethod def insert(cls, user): dataDict = {} dataDict["username"] = user.username dataDict["password"] = user.password if cls.mySQL.insert(dataDict): cls.redis.set(user.username,user.password) return 1 else: print("注冊(cè)失敗,服務(wù)器繁忙!!!") return 0 # 修改密碼 @classmethod def changePasswd(cls, user): dataDict = {'changeCol': 'password = %s'%user.password, 'caluse' : 'username = %s'%user.username} if cls.mySQL.update(dataDict): cls.redis.set(user.username,user.password) return 1 else: print("修改密碼失敗,服務(wù)器繁忙!!!") return 0 # 注銷(xiāo)用戶(hù) @classmethod def deleteUser(cls, user): dataDict = {'username' : user.username} if cls.mySQL.delete(dataDict): cls.redis.delete(user.username) return 1 else: print("修改密碼失敗,服務(wù)器繁忙!!!") return 0
5、Utils工具包
用來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)的增刪改查,可以被不同的系統(tǒng)調(diào)用。
''' @author ldc ''' import pymysql import redis as redis ''' MySQL增刪改查操作類(lèi) ''' class MySQLUtil: def __init__(self,dbName,tableName): self.dbName = dbName self.tableName = tableName # 連接數(shù)據(jù)庫(kù),并生成全局可用的連接對(duì)象和查詢(xún)游標(biāo) def connect(self): self.conn = pymysql.connect( host='localhost', user='root', password="123456", database=self.dbName, port=3306, ) self.cursor = self.conn.cursor() # 關(guān)閉全局游標(biāo),斷開(kāi)全局連接 def disconnect(self): self.cursor.close() self.conn.close() # 查詢(xún)用戶(hù)名是否存在 def exists(self,dataDict): caluse = '' for key,value in dataDict.items(): caluse += key + '="'+ value + '"' # print(caluse) sql = """ select * from %s where %s ; """ % (self.tableName, caluse) return self.execute(sql) # 驗(yàn)證用戶(hù)名和密碼是否正確 def query(self, dataDict): # 查詢(xún)子條件拼接 caluse = '' for key, value in dataDict.items(): caluse += key + '="' + value + '" and ' caluse = caluse[:-4] # print(caluse) sql = """ select * from %s where %s; """% (self.tableName, caluse) return self.execute(sql) # 添加新用戶(hù) def insert(self, dataDict): # sql語(yǔ)句拼接 columns = '' values = '' for key, value in dataDict.items(): columns += key + ',' values += '"' + value + '",' columns = columns[:-1] values = values[:-1] sql = """ insert into %s (%s) VALUES (%s); """ % (self.tableName, columns,values) # print(sql) return self.execute(sql) # 更新 def update(self, dataDict): # sql語(yǔ)句拼接 changeCol = dataDict['changeCol'] #要改變值的列名 caluse = dataDict['caluse'] #要改變值的子條件 sql = 'update %s set %s where %s'%(self.tableName,changeCol,caluse) return self.execute(sql) # 刪除 def delete(self, dataDict): # sql語(yǔ)句拼接 caluse = '' for key,value in dataDict.items(): caluse += key + '="' + value + '"' sql = """ delete from %s where %s; """ % (self.tableName,caluse) # print(sql) return self.execute(sql) # print(sql) # 執(zhí)行sql語(yǔ)句 def execute(self, sql): self.connect() affected = 0 try: affected = self.cursor.execute(sql) except BaseException as e: print(e) affected = 0 finally: self.conn.commit() self.disconnect() return affected ''' redis增刪改查操作類(lèi) ''' class RedisUtil: # redis連接 @classmethod def connect(cls): cls.client = redis.Redis( host='localhost', port=6379, db=1, password='123456', ) # 判斷鍵是否存在 @classmethod def exists(cls,key): return cls.client.exists(key) # 存儲(chǔ)鍵值, @classmethod def set(cls,key,value): # 鍵值存儲(chǔ)在緩存中,保留時(shí)間為30秒 cls.client.setex(key,value,30) # 獲取鍵值 @classmethod def get(cls,key): res = cls.client.get(key).decode("utf-8") return res # 刪除鍵值 def delete(cls, key): cls.client.delete(key)
6、部分功能展示
注冊(cè):
登錄:
改密:
注銷(xiāo):
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Python面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)與進(jìn)階教程》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結(jié)》及《Python入門(mén)與進(jìn)階經(jīng)典教程》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
- 詳解Python做一個(gè)名片管理系統(tǒng)
- python實(shí)現(xiàn)名片管理系統(tǒng)
- python實(shí)現(xiàn)簡(jiǎn)單名片管理系統(tǒng)
- python面向?qū)ο髮?shí)現(xiàn)名片管理系統(tǒng)文件版
- Python版名片管理系統(tǒng)
- python實(shí)現(xiàn)一個(gè)函數(shù)版的名片管理系統(tǒng)過(guò)程解析
- Python實(shí)現(xiàn)的銀行系統(tǒng)模擬程序完整案例
- python爬蟲(chóng)爬取微博評(píng)論案例詳解
- Python實(shí)現(xiàn)的爬取豆瓣電影信息功能案例
- Python綜合應(yīng)用名片管理系統(tǒng)案例詳解
相關(guān)文章
使用PyTorch處理多維特征輸入數(shù)據(jù)的完美實(shí)現(xiàn)
在機(jī)器學(xué)習(xí)和深度學(xué)習(xí)領(lǐng)域,我們經(jīng)常會(huì)面對(duì)具有多維特征輸入的問(wèn)題,這種情況出現(xiàn)在各種應(yīng)用中,包括圖像識(shí)別、自然語(yǔ)言處理、時(shí)間序列分析等,PyTorch是一個(gè)強(qiáng)大的深度學(xué)習(xí)框架,在本篇博客中,我們將探討如何使用PyTorch來(lái)處理多維特征輸入數(shù)據(jù)2023-10-10使用python socket分發(fā)大文件的實(shí)現(xiàn)方法
今天小編就為大家分享一篇使用python socket分發(fā)大文件的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Python3 加密(hashlib和hmac)模塊的實(shí)現(xiàn)
本篇文章主要介紹了Python3 加密(hashlib / hmac)模塊的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11淺談Python中os模塊及shutil模塊的常規(guī)操作
這篇文章主要介紹了淺談Python中os模塊及shutil模塊的常規(guī)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04詳解win10下pytorch-gpu安裝以及CUDA詳細(xì)安裝過(guò)程
這篇文章主要介紹了win10下pytorch-gpu安裝以及CUDA詳細(xì)安裝過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Python小程序編程實(shí)現(xiàn)一鍵自動(dòng)整理文件解壓文件
這篇文章主要為大家介紹了Python小程序編程實(shí)現(xiàn)一鍵自動(dòng)整理文件解壓文件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Anaconda+Pycharm+Pytorch虛擬環(huán)境創(chuàng)建(各種包安裝保姆級(jí)教學(xué))
相信很多時(shí)候大家都會(huì)用到虛擬環(huán)境,他具有可以讓你快速切換不同的python版本,本文主要介紹了Anaconda+Pycharm+Pytorch虛擬環(huán)境創(chuàng)建,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10Python創(chuàng)建一個(gè)元素都為0的列表實(shí)例
今天小編就為大家分享一篇Python創(chuàng)建一個(gè)元素都為0的列表實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11