前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python用flask框架开发的(python做一个登录注册界面)

python用flask框架开发的(python做一个登录注册界面)

作者头像
全栈程序员站长
发布2022-07-29 21:52:35
1.3K0
发布2022-07-29 21:52:35
举报

大家好,又见面了,我是你们的朋友全栈君。

Python-Flask构建用户注册登录后端逻辑架构

1、项目结构

在这里插入图片描述
在这里插入图片描述

2、app.py

代码语言:javascript
复制
from flask import Flask,render_template
from controller.user_controller import user_controller
from datetime import timedelta
import os

app=Flask(__name__)
app.register_blueprint(user_controller)

app.config['JSON_AS_ASCII'] = False
app.config['SECRET_KEY'] = os.urandom(24)   #设置为24位的字符,每次运行服务器都是不同的,所以服务器启动一次上次的session就清除。
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)  #设置session的保存时间。

@app.route('/')
def index():
	return render_template('index.html')

if __name__ == "__main__":
	#在生产环境中host='0.0.0.0'
	app.run(host='127.0.0.1',port=5020,debug=False)

3、user_controller

代码语言:javascript
复制
from flask import Flask,Blueprint,request,render_template,session
from dao.userdao import UserDAO
from entity.user_entity import UserEntity

user_controller=Blueprint('user_controller',__name__)

userdao=UserDAO()
userentity=UserEntity()

@user_controller.route('/login',methods=['POST'])
def login():
    info=''
    userentity.telphone=request.form['telphone']
    userentity.password=request.form['password']
    res=userdao.GetLoginInfo(userentity)
    if res==None:
        info='无用户信息,请注册'
        return render_template('index.html',info=info)
    elif res[0]==userentity.password:
        info='登录成功'
        session['telphone']=userentity.telphone
        return render_template('index.html',info=info)
    else:
        info='登录失败'
        return render_template('index.html',info=info)
    return render_template('index.html',info='Unknow Error!!!')

@user_controller.route('/register',methods=['POST'])
def register():
    info=''
    userentity.telphone=request.form['telphone']
    userentity.password=request.form['password']
    password_again=request.form['password_again']
    res=userdao.GetSameInfo(userentity)
    if res:
        info='手机号已被使用,请更换手机号重试'
        return render_template('index.html',info=info)
    elif userentity.password!=password_again:
        info='两次密码不一致'
        return render_template('index.html',info=info)
    else:
        info='注册成功'
        userdao.CreateUser(userentity)
        return render_template('index.html',info=info)
    return render_template('index.html',info='Unknow Error!!!')

@user_controller.route('/exit',methods=['GET'])
def exit():
    info=''
    res=session.get('telphone')
    if res==None:
        info='未登录'
        return render_template('index.html',info=info)
    else:
        session['telphone']=None
        info='账号已成功注销'
        return render_template('index.html',info=info)
    return render_template('index.html',info='Unknow Error!!!')

4、basedao

代码语言:javascript
复制
import pymysql # 导入数据的api包
from logger.syslogger import logger

#数据库访问封装的基类
class BaseDAO():

    # 1. 这些参数做私有化,就体现了封装安全性的好处
    def __init__(self, host='IP', name='root', pwd='PWD', port='3306', schema='talk_system', charset='utf8mb4'):
        self.__host = host
        self.__name = name
        self.__pwd = pwd
        self.__port = port
        self.__schema = schema
        self.__charset = charset
        self.__conn = None
        self.__cursor = None
        pass

    # 2. 编写建立数据库连接的公有方法(通用的)
    def getConnection(self):
        try:
            self.__conn = pymysql.connect(self.__host, self.__name, self.__pwd, self.__schema, charset=self.__charset)
        except (pymysql.MySQLError, pymysql.DatabaseError, Exception):
            logger.error("数据库连接异常:" + self.__host)
            pass
        self.__cursor = self.__conn.cursor()
        pass

    # 3. 封装一个通用的对数据库进行操作的方法
    def execute(self, sql, params=None, isBatch=False):
        try:
            # self.getConnection() # 每次连接的是独立的一个连接
            if self.__conn and self.__cursor:
                if params:
                    # print('not None')
                    # print(parms)
                    if isBatch:
                        return self.__cursor.executemany(sql, params)
                        pass
                    else:
                        return self.__cursor.execute(sql, params)
                else:
                    return self.__cursor.execute(sql)
                pass
        except:
            logger.error("执行SQL:" + sql + " params:" + str(params) )
            self.__cursor.close()
            self.__conn.close()
            pass
        pass

    # 调用存储过程
    def executeProc(self, sql, params=None):
        try:
            if self.__conn and self.__cursor:
                if params:
                    return self.__cursor.callproc(sql, params)
                else:
                    return self.__cursor.callproc(sql)
                pass
        except:
            logger.error("执行SQL:" + sql + " params:" + str(params))
            self.__cursor.close()
            self.__conn.close()
            pass
        pass

    # 4. 为了支持事务管理,把对数据库的关闭的动作提取出来,封装成独立的方法
    def close(self):
        if self.__cursor and self.__conn:
            self.__cursor.close()
            self.__conn.close()
        pass

    # 5. 为了支持事务管理,把对数据库事务提交的动作提取出来,封装成独立的方法
    def commit(self):
        # print("----------")
        self.__conn.commit()
        pass

    # 6. 如果出现异常情况,事务要回滚
    def rollback(self):
        self.__conn.rollback()
        pass

    # 查询操作
    def fetchall(self, sql, params=None):
        self.execute(sql, params)
        return self.__cursor.fetchall()
        pass

    # 查询操作
    def fetchone(self, sql, params=None):
        self.execute(sql, params)
        return self.__cursor.fetchone()
        pass

    # 执行存储过程
    def fetchproc(self, sql, params=None):
        self.executeProc(sql, params)
        return self.__cursor.fetchall()
        pass
    pass

5、userdao

代码语言:javascript
复制
from dao.basedao import BaseDAO
from logger.syslogger import logger
import math

class UserDAO(BaseDAO):
    #注册查重验证
    def GetSameInfo(self,user):
        sqlSelect = "select id from user where telphone=%s;"
        params = (user.telphone,)
        try:
            super().getConnection()
            result = super().fetchone(sqlSelect,params)
            super().commit()
            return result
        except Exception as e:
            logger.error("执行SQL:" + str(sqlSelect) + " 出现异常,params:" + str(e))
        finally:
            super().close()

    # 新用户注册
    def CreateUser(self, user):
        try:
            super().getConnection()
            sqlCreate = "insert into user (id,telphone,password) values (NULL ,%s, %s);"
            params = (user.telphone,user.password)
            result = super().execute(sqlCreate, params)
            super().commit()
            return result
        except Exception as e:
            super().rollback()
            logger.error("执行SQL:" + sqlCreate + " 出现异常,params:" + params + str(e))
        finally:
            super().close()

    #登录验证
    def GetLoginInfo(self,user):
        sqlSelect = "select password from user where telphone=%s;"
        params = (user.telphone,)
        try:
            super().getConnection()
            result = super().fetchone(sqlSelect, params)
            super().commit()
            return result
        except Exception as e:
            logger.error("执行SQL:" + str(sqlSelect) + " 出现异常,params:" + str(e))
        finally:
            super().close()

6、user_entity

代码语言:javascript
复制
class UserEntity():
    def __init__(self):
        self.__id=None
        self.__telphone=None
        self.__password=None

    @property
    def id(self):
        return self.__id

    @id.setter
    def id(self, id):
        self.__id = id

    @property
    def telphone(self):
        return self.__telphone

    @telphone.setter
    def telphone(self, telphone):
        self.__telphone = telphone

    @property
    def password(self):
        return self.__password

    @password.setter
    def password(self, password):
        self.__password = password

7、syslogger

代码语言:javascript
复制
#-*- coding:utf-8 -*-
''' demo03-logging-file.py ------------------------ 日志写入文件 @Copyright: Chinasoft International·ETC '''

# 导入模块
import logging
import os
import time

# 首先,创建并设置日志logger对象
# 创建logger对象并设置信息源对象名称
logger = logging.getLogger('mainlogger')
# 设置日志的输出的输出级别
logger.setLevel(logging.DEBUG)
# 设置日志的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')


# 其次,创建并设置文件处理器FileHandler对象
dirPath = os.path.join(os.getcwd(), 'log')
if not os.path.exists(dirPath):
    os.mkdir(dirPath)
logFileName = time.strftime('%Y%m%d', time.localtime())+'.log'
logPath = dirPath + os.sep + logFileName
# 创建FileHandler对象
fileHandler = logging.FileHandler(logPath)
# 设置Filehandler对象的写入信息级别
fileHandler.setLevel(logging.DEBUG)
# 设置FileHandler对象的信息格式
fileHandler.setFormatter(formatter)


# 创建一个 StreamHandler对象
consoleHandler = logging.StreamHandler()
# 设置控制台输出的信息级别
consoleHandler.setLevel(logging.DEBUG)
# 设置consoleHandler对象的信息格式
consoleHandler.setFormatter(formatter)

# 最后,logger对象添加Handler对象替换原有默认的Handler对象
logger.addHandler(fileHandler)
logger.addHandler(consoleHandler)



# 测试输出不同级别的日志信息
''' logger.fatal('系统崩溃或发生致命性错误,导致程序中断时需要输出的信息') logger.critical('系统资源浩劫时需要输出的信息(一般很少用到)') logger.error('系统报错异常时需要输出的信息') logger.warning("系统运行警告时需要输出的信息") logger.info("一般信息数据") logger.debug("测试调试时需要输出的信息数据") '''

8、index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    { 
   { 
   info}}
    <h2>登录</h2>
    <form action="/login" method="post">
        <label for="username">手机号:</label>
        <input type="text" name="telphone" required>
        <label for="password">密码:</label>
        <input type="text" name="password" required>
        <button type="reset">重置</button>
        <button type="submit">提交</button>
    </form>
    <h2>注册</h2>
    <form action="/register" method="post">
        <label for="telphone">手机号:</label>
        <input type="text" name="telphone" required>
        <label for="password">密码:</label>
        <input type="text" name="password" required>
        <label for="password_again">密码二次确认:</label>
        <input type="text" name="password_again" required>
        <button type="reset">重置</button>
        <button type="submit">提交</button>
    </form>
    <a href="/exit">账号注销</a>
</body>

</html>

9、程序启动效果图

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

——————————————————————————————————————————————

在这里插入图片描述
在这里插入图片描述

10、备注 这个架构只考虑最简单的登录、注册、注销逻辑,之后优化可以注重前端输入限制、placeholder、登录密码加盐Hash等等

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129775.html原文链接:https://javaforall.cn

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022年4月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python-Flask构建用户注册登录后端逻辑架构
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com