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

Python-Flask构建用户注册登录后端逻辑架构1、项目结构2、app.pyfromflaskimportFlask,render_templatefromcontroller.user_controllerimportuser_controllerfromdatetimeimporttimedeltaimportosapp=Flask(__name__)app.register_blueprint(user_controller)app.config[‘JS

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

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

1、项目结构
在这里插入图片描述
2、app.py

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

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

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

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

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

#-*- 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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • gtest测试用例_数据字典简单例子

    gtest测试用例_数据字典简单例子#includeintfun1(){return10;}classtest:public::testing::Test{public:intfun2(){return1;};};TEST(fun1,test_fun){EXPECT_EQ(10,fun1());//单个函数的测试}TE

  • pycharm如何调试python程序_Pycharm断点调试Python程序的步骤方法

    pycharm如何调试python程序_Pycharm断点调试Python程序的步骤方法利用Pycharm断点调试Python程序的方法1.代码准备没有语法错误的Python程序:#!/usr/bin/pythonimportnumpyasnpclassNetwork:def__init__(self,sizes):self.num_layers=len(sizes)self.sizes=sizesself.biases=[np.random.randn(y,1)for…

    2022年10月30日
  • 搭建LAMP架构_redis搭建集群

    搭建LAMP架构_redis搭建集群搭建LAMP架构一、LAMP架构概述1、LAMP简介LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整台系统和相关软件,能够提供动态web站点服务及其应用开发环境。LAMP是一个缩写词,具体包括Linux操作系统,Apache网站服务器,MySQL数据库服务器,PHP(或perl,Python)网页编程语言。2、LAMP构成组件(1)Linux系统:LAMP架构的基础,提供用于支撑Web站点的操作系统(2)Apache网站服务:LAMP架构的前端,向用户提供网站服务、发送网

    2022年10月10日
  • linux PS1 提示符定义[通俗易懂]

    linux PS1 提示符定义[通俗易懂]PS1:就是用户平时的提示符。PS2:第一行没输完,等待第二行输入的提示符。Linux系统提示符是用系统变量PS1来定义的。一般系统默认的形式是:[username@host工作目录]$.用e

  • 数仓建设 | ODS、DWD、DWM等理论实战(好文收藏)

    数仓建设 | ODS、DWD、DWM等理论实战(好文收藏)本文目录:一、数据流向二、应用示例三、何为数仓DW四、为何要分层五、数据分层六、数据集市七、问题总结导读数仓在建设过程中,对数据的组织管理上,不仅要根据业务进行纵向的主题域划分,还需要横向的数仓分层规范。本文作者围绕企业数仓分层展开分析,希望对你有帮助。因文章太长,本文不是完结版,文末可获取完整PDF版从事数仓相关工作的人员都知道数仓模型设计的首要工作之一就是进行模型分层,可见模型分层在模型设计过程中的重要性,确实优秀的分层设计是一个数仓项目能否建设成功的核心要素,让数

  • 简要说明continue命令和break命令的不同_continue的用法

    简要说明continue命令和break命令的不同_continue的用法break命令可以带一个参数,一个不带参数的break循环只能退出最内层的循环,而breakN可以退出N层循环。continue命令也可以带一个参数,一个不带参数的continue命令只去掉本次循环的剩余代码,而continueN将会把N层循环剩余的代码都去掉,但是循环的次数不变。#!/bin/shforiin”abcd”doech

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号