Python注册登录系统 / 控制台交互数据库引入


前言

一、项目需求;

1、实现一个基于命令行的用户注册功能。
2、用户注册时必须要输入 用户名、密码、手机号码,用针对用户的输入必须进行验证。
3、用户名的规则:只能是大小写字母或数字,且不能以数字开头,长度为5~12位。
4、密码的规则:密码必须且只能由大小写和数字组成,长度为6~15位。
5、手机号码的规则:按照标准的中国手机号码规则进行校验。
6、如果校验成功,则允许用户注册,注册信息保存于数据库中。

1、绘制菜单,用户可以自行决定下一步做什么:登录、注册、改密、改电话、退出。
2、支持多用户注册,注册时,如果已经存在的用户名不能注册。
3、密码输入失败3次,则不再允许当前用户登录,退回到主菜单。
4、用户登录成功以后,可以修改密码和电话号码,同样需要进行正确性校验。
5、用户在输入用户名、密码或电话时,如果输错超过3次,则结束运行。
(1)利用MySQL数据库等完成注册、登录、修改密码等操作。
(2)记录用户操作的历史记录(登录、注册、改密、改电话)。

python控制台模拟系统,登录注册修改用户信息等功能

Mon 06 Mon 13 前逻辑注释 编写代码 调式解决功能bug 项目需求 pythone registers the login system

一、主页菜单(main.py)

实现思路:
简单的给控制台页面模拟出来,设置调用菜单的函数,方便后面代码执行后返回主菜单
里面主要用数字去直接做调用其他文件关键函数而已,没什么思路,那个if else判断

细节就不在外面提了,全写在代码里,和生活中及人情世故

统统注释起来

##本菜单引用其他文件函数 *safe14包里面的.mysql_system包以.取下一级,import调用多个文件
from safe14.mysql_system import regist, login,storage

#select函数
def select():
    print('*' * 46)##第一排46个星星
    print('*' * 7, 'Welcome To Woniuxy Info System', '*' * 7)
    print('*' * 2, '注册-0', '*' , '登录-1', '*', '改密-2','*','改电话-3','*','返回-9','*' * 2)
    print('*' * 46)
    ##以此类推46、7、2、46各行星星数其他的是绘制菜单的字符串

	##定个变量flag将input里的值保存到flag里,是用户输入的,并给用户提示后面跟上
    flag = input('please input menu number:')

	##if判断0就去调用注册的函数进行注册,否则1、2、3、9一次类推
	##否则用户输入其他数字,输入哪个去哪个
    if flag=='0':
        regist.regist()#注册
    elif flag=='1':#登录
        login.loginfo()
    elif flag=='2':#改密码
        login.login1()
    elif flag=='3':#改电话
        login.login2()
    elif flag=='9':
        exit('bye~')
    ##胡乱输入就给直接退出程序
    else:
        storage.stor("system.log", "输入不符合规则,退出程序")
        exit('input error~')

if __name__ == '__main__':
    select()

菜单页面展示👇
在这里插入图片描述

二、正则校验(check.py)

实现思路
为了将代码提现的更加模块化,将所有正则校验放到单独一个文件里。
以方便其他注册用户、及修改用户信息校验直接调用此文件。干净易懂,方便以开发团队的思路去写代码。
里面主要有三大校验:用户名、密码、手机号(ASCII)校验。
下方有校验需求注释👇


'''
用户名的规则:只能是大小写字母或数字,且不能以数字开头,长度为5~12位
'''
import re##引用内置正则表达式模块
import main##引用主菜单页面模块
def check_user(username):#定义个函数,备用个参数username
    pattern="^[a-zA-Z][0-9a-zA-Z]{4,11}$"
    ##上面定义正则规则,下面正则固定写法re.match,规则在先字符串在后,储存在res变量中,全拼result;结果
    res=re.match(pattern=pattern,string=username)
    if res:#这里if判断如果值出来个给返回True反之False
        return True
    else:
        # print("用户名只能是大小写字母或数字,且不能以数字开头,长度为5~12位")
        return False
    #re.match:匹配成功返回一个match对象:<re.Match object; span=(0, 5), match='lency'>
'''
密码的规则:密码必须且只能由大小写字母和数字组成,长度为6~15位
print(ord(st)) #a-97 z-122 A-65 Z=90 0-48 9-57 将字符转换成ASCII
print(chr(97)) #将ASCII值转换成对应的字符
'''
def check_pwd(pwd):
    low=0
    up=0
    num=0
    if len(pwd)>=6 and len(pwd)<15:
        #原生比较/ASII数值比较
        for p in pwd:
        ##这里可参照ascii表来查明意义
            if ord(p)>=97 and ord(p)<=122 :
                # print('小写字母')
                low+=1
            elif ord(p)>=65 and ord(p)<=90 :
                # print('大写字母')
                up+=1
            elif ord(p)>=48 and ord(p)<=57 :
                # print('数字')
                num+=1
            else:
                return False
    #这里if判断,他们都通过了这些要求就给他们加1,如果最后的结果他们这几个条件都有1,则给它通过返回True
    # print(low,up,num)
    if up>=1 and low>=1 and num>=1:
        return True
    else:
        # print("密码必须且只能由大小写字母和数字组成,长度为6~15位:")
        # main.select()
        return False

'''
手机号码的规则:按照标准的中国手机号码规则进行校验
'''
def check_tel(tel):
    pattern = "^1[3-9]\d{9}$"
    if(re.match(pattern,tel)):#固定写法,规则在线,字符串在后
        return True
    else:
        # print("请按照中国手机号码输入你的手机号")
        # main.select()
        return False
##整体思路,就是将他们成功返回True,失败则返回False,这些有用,后面会使用到这些返回值。

三、数据库操作(db.py)

mysql(DML,DQL)

实现思路
python:建立连接(字符编码),创建游标,sql查询,获取结果,关闭游标,关闭连接。
将注册信息,及修改用户信息,函数化写入数据库中,方便其他脚本调用
尽可能保证参数化,利用性强,模块化。
下方有校验需求注释👇

import pymysql##引用数据库内置模块
from pymysql import IntegrityError##引用内置函数
from safe14.mysql_system import main, storage##引入菜单及日志所有函数


def query(username):#查询,校验注册及登录
     con=pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
##pymysql.connect固定写法,后面根据格式要求输入对应的连接信息,和php有些不一样的点在于,直接在连接里面设置utf8编码格式
     cursor=con.cursor()#拿着游标在做查询
     sql=f"select password from user where username='{username}';"
   	 ##将sql语句参数化sql前面写个f里面的username给它用花括号参数化
     cursor.execute(sql)#查sql语句的
     results = (cursor.fetchone())##封装查询结果,fetchone一条,固定写法
     if  results is None:##如果查询结果是空
         storage.stor("system.log", f"‘{username}’用户不存在,登陆失败")##写入日志系统
         print(f"用户'{username}'不存在")##直接打印它不存在
         ##关闭查询,关闭数据数据库连接。保证占用资源损耗减少
         cursor.close()
         con.close()
         main.select()##不存在的用户,直接给它返回至主菜单
     else:##否则的话一定是直接成功,将results返回值取下标0直接取出来
         resul = results[0]  # 取一条数据
         cursor.close()
         con.close()
         return resul#给个返回值

##下面判断密码和电话的逻辑完全相同
##定义好连接,然后定好游标及sql修改语句并参数化
##执行连接和sql语句/固定写法cursor.execute()
##!!重重之中记得提交//固定写法con.commit()

def dml_alter_pwd(password,username):#修改用户密码
    con = pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
    cursor=con.cursor()
    sql=f"update user set password='{password}' where username='{username}';"
    cursor.execute(sql)
    con.commit()#提交

def dml_alter_phone(tel,username):#修改用户电话号
    con = pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
    cursor=con.cursor()
    sql=f"update user set tel='{tel}' where username='{username}';"
    cursor.execute(sql)
    con.commit()#提交

def dml_insert(username,password,tel):#注册信息储存
    con = pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
    cursor=con.cursor()
    sql=f"insert into user(username,password,tel) values('{username}','{password}','{tel}');"
    ##这里注册信息用了个python报错异常处理try/except
    try:
        cursor.execute(sql)##执行
    except IntegrityError  as e:##将这条开头的报错信息as成e
        if 'Duplicate' in str(e):##如果Dup在e报错里面
            storage.stor("system.log", f"'{username}'用户已存在,请重新注册")##写入日志
            print('用户名重复,注册失败')##给用户提示

    else:##这里逻辑就简单了,如果里面没有用户传入的用户直接,else写数据库里
        con.commit()#直接提交
        storage.stor("system.log", f"用户'{username}'注册成功")##写入日志
        print('注册成功')##提示成功

    finally:##不论啥结果,直接返回至菜单。
        main.select()

整体数据库脚本逻辑跑通很好写的。固定写法就那么几个

四、注册系统(regist.py)

实现思路
代码量少的可怜即可完成注册。
正解且简单,直接引用四个脚本
这回之前check.py返回值的True 和 False直接用上了
下方有校验需求注释👇

from safe14.mysql_system import check##引用正则判断脚本
from safe14.mysql_system import storage##引用日志系统函数
from safe14.mysql_system import main##引用菜单
from safe14.mysql_system import db##引用数据库操作

def regist():
    username = input('请输入用户名:')
    if check.check_user(username)!=True:
        storage.stor("system.log", f"用户名复杂度不符合要求,用户'{username}'注册失败")
        print('用户名只能是大小写字母或数字,且不能以数字开头,长度为5~12位')
        main.select()
    password = input('请输入密码:')
    if check.check_pwd(password)!=True:
        storage.stor("system.log", f"密码复杂度不符合要求,用户'{username}'注册失败")
        print('密码必须且只能由大小写字母和数字组成,长度为6~15位:')
        main.select()
    tel = input('请输入手机号:')
    if check.check_tel(tel)!=True:
        storage.stor("system.log", f"手机号不符合要求,用户'{username}'注册失败")
        print('请按照中国手机号码输入你的手机号')
        main.select()
    ##实现用户体验感极好,哪里规则输错了,直接给提示,前面三个if判断,哪里不符合规则,直接返回主菜单重新走一遍
    ##并且将失败注册并记录进日志文件中。
    else:
        db.dml_insert(username,password,tel)
    ##如果if全通过 直接 else,给他写入db文件,调用dml函数username,password,tel,insert插入数据库中。
    ##数据库有校验,如果有用户输入的用户,反之不让注册

五、登录系统(login.py)

实现思路
主要有三大块函数:
登录校验,修改密码、电话判断,三次失败直接返回主菜单
改用户信息,需要登录后才可更改,为了不能随便让别人更改
下方有注释👇

import main
from safe14.study import check
from safe14.mysql_system import db, storage


def login1():#改密码
    count = 0##定义个判断输错初始值
    for i in range(3):#限定三次范围
        username = input('请输入你的用户名:')
        password = input('请输入你的密码:')
        res = db.query(username)##请求一下数据库,看看有没有当前用户,锁定用户后面的用户信息也会跟着一起出来,结果res封装
        if password != res:##这里不判断用户名,因为即便你随便输入的用户名,查找对应的密码信息,如果没有此用户,里面也没有随便输入的用户名的密码信息。
            storage.stor("system.log", f"登录失败'{count+1}'次")##将登录失败次数记录在log日志中
            print('登录失败')##给登录失败提示
            count += 1##失败一次直接给+1次
            if count == 3:##如果输错3次
                storage.stor("system.log", f"登录失败共'{count}'次")##统计次数记录日志中
                print('你已登录失败3次,请登录成功后再修改密码')##给提示
                main.select()##直接给他返回至主菜单页面
                count = 0##次数清零,解决下次循环出现报错清空
        else:
            count = 0
            storage.stor("system.log", f"用户'{username}'登录成功,")##否则直接登录成功,并记录日志,次数给归零
            newpassword = input('请输入你的新密码:')##输入新密码
            if check.check_pwd(newpassword) == True:##这里再次调用密码校验正则判断
                newwpassword = input('请再次输入你的新密码:')##再次输入一次密码,为了让用户输入密码别再忘了,用于用户新密码加深记忆
                if newpassword == newwpassword:##如果新输入的密码等于重新输入的新密码
                    db.dml_alter_pwd(newwpassword, username)##直接将重新输入的新密码写入数据库,并且指定哪个用户的新密码
                    storage.stor("system.log", f"用户‘{username}’修改密码成功")##写入日志某某修改成功
                    print('密码修改成功')##给修改成功提示
                    main.select()##返回主菜单页面
                else:##否则
                    storage.stor("system.log", f"2次输入的密码不一致,用户‘{username}’修改密码失败")##二次输入不一致,写入日志系统
                    print('2次输入的密码不一致,修改密码失败')##给用户提示
                    main.select()##直接回你老家吧,二次都失败了
            else:##大if的判断,如果你输入的新密码不符合复杂度
                storage.stor("system.log", "不符合密码复杂度要求,修改密码失败")##存入日志某某密码修改失败
                print('不符合密码复杂度要求,修改密码失败')##给用户提示
                main.select()##返回主菜单

###这里该菜单逻辑思路与 修改密码完全相同套路###不在做过多解释
def login2():#改电话
    count = 0
    for i in range(3):
        username = input('请输入你的用户名:')
        password = input('请输入你的密码:')
        res = db.query(username)
        if password != res:
            storage.stor("system.log", f"登录失败'{count+1}'次")
            print('登录失败')
            count += 1
            if count == 3:
                storage.stor("system.log", f"登录失败共'{count}'次,")
                print('你已登录失败3次,请登录成功后再修改密码')
                main.select()
                count = 0
        else:
            count = 0
            storage.stor("system.log", f"用户'{username}'登录成功,")
            newtel = input('请输入你的新号码:')
            if check.check_tel(newtel) == True:
                newwtel = input('请再次输入你的新号码:')
                if newtel == newwtel:
                    db.dml_alter_phone(newwtel, username)
                    storage.stor("system.log", f"用户‘{username}’修改号码成功")
                    print('号码更改成功')
                    main.select()
                else:
                    storage.stor("system.log", f"2次输入的号码不一致,用户‘{username}’修改号码失败")
                    print('2次输入的号码不一致,修改号码失败')
                    main.select()
            else:
                storage.stor("system.log", "不符合号码复杂度要求,修改号码失败")
                print('不符合号码复杂度要求,修改号码失败')
                main.select()

def loginfo():#包括登录成功和登录失败三次
    count = 0##初始值给0
    for i in range(3):##3次失败范围
        username = input('请输入你的用户名:')
        password = input('请输入你的密码:')
        res = db.query(username)
        if password != res:
            storage.stor("system.log",f"登录失败'{count+1}'次")
            print('登录失败')
            count += 1
            if count == 3:
                storage.stor("system.log", f"登录失败共'{count}'次")
                print('你已登录失败3次,返回主界面')
                main.select()
                count = 0
        else:
            storage.stor("system.log", f"用户‘{username}’登录成功")
            print('登陆成功')
            main.select()
            count = 0
##整体思路如最上方一样,登录失败三次判断,记录日志,调用数据库用户信息数据,是否有。如果用户都写对,给他进入主菜单页面。

这里为了代码简洁直接login1()、login2() 了。
如果团队开发这边建议,标准函数命名,与其代码含义相关
函数格式如:驼峰

六、日志系统(storage.py)

实现思路
调用个python内置时间模块
没什么思路逻辑,主要就是一个写入方法,前面做的记录,往日志函数里传值就行了

import time##调用time内置模块
def stor(file,cont):#日志记录,需要各个记录日志信息两个选项中的第一个传递传文件名参数,第二个就是其他记录变量信息传递给cont的参数。

##ymdHMS写出你想要的时间格式,time.time返回当前时间的时间戳,time.localtime格式化时间戳为本地的时间.
    strtim = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    ##time.strftime函数用于格式化时间,返回以可读字符串表示的当地时间
    with open(file,'a+',encoding='utf8') as fp:##打开file文件参数,追加读写,设置utf8编码集,命名fp。
        fp.write(strtim +'  ' +cont+ "\n")##fp追写、然后就是日志格式了;时间在前+拼接中间空格隔开+记录字段阶段给个换行。

七、日志文件(system.log)

用于储存日志记录信息条目

2022-10-29 21:51:59 用户’admin’登录成功,
2022-10-29 21:52:10 密码错误,用户‘admin’登录失败‘1’次
2022-10-29 21:52:13 密码错误,用户‘admin’登录失败‘2’次
2022-10-29 21:52:15 密码错误,用户‘admin’登录失败‘3’次
2022-10-29 21:52:15 你已登录失败’4’次,
2022-10-29 21:55:23 用户‘admin’登录失败
2022-10-29 21:55:26 用户‘admin’登录失败
2022-10-29 21:55:30 用户‘admin’登录失败
2022-10-29 21:55:30 你已登录失败3次
2022-10-29 21:55:39 用户‘admin’登录失败
2022-10-29 22:07:45 登录失败’1’次
2022-10-29 22:07:48 登录失败’2’次
2022-10-29 22:07:50 登录失败’3’次
2022-10-29 22:07:50 登录失败’4’次
2022-10-29 22:08:12 登录失败’1’次
2022-10-29 22:08:14 登录失败’2’次
2022-10-29 22:10:26 登录失败’1’次
2022-10-29 22:10:30 登录失败’2’次
2022-10-29 22:10:30 登录失败’3’次
2022-10-29 22:11:22 密码复杂度不符合要求,注册用户‘admin’失败
2022-10-29 22:16:54 登录失败’1’次
2022-10-29 22:16:56 登录失败’2’次
2022-10-29 22:17:01 登录失败’3’次
2022-10-29 22:17:01 登录失败共’3’次
2022-10-29 22:17:47 登录失败’1’次
2022-10-29 22:18:05 用户‘admin’登录成功
2022-10-29 22:26:55 注册用户‘wangwu’成功
2022-10-31 09:31:31 用户‘admin’登录成功


全部文件

check.py(正则及ASII判断,注册信息校验)
db.py(数据库操作:DML,DQL/mysql)
login.py(登录系统及修改用户信息)
main.py(主页菜单)
regist.py(注册系统及校验引用)
storage.py(日志系统关键代码)
system.log(日志文件)



异常处理报错头排查方法:
1、查看代码引用时迷路使用ctrl+左键,追踪
2、多使用print打印出代码走向、多print有意无害
3、调用其他脚本函数引用文件,如找不到时点下红色灯泡
4、控制型代码注意缩进位置
5、调用函数,传参思路要明确过程及走向


总结

python控制台,实现用户注册、登录、修改密码、及各种校验
对注册登录系统交互初学者十分友好,对安全漏洞,本章无任何声明。

此篇文章纯手打,如有遗漏输错请包涵
希望能帮助到你

  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值