欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Flask实战----做了一个简易版CSDN

发布时间:2025/3/19 编程问答 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Flask实战----做了一个简易版CSDN 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

Flask实战

  • 数据库设计
    • 创建数据表
    • 创建数据库操作类
      • exc_info()
      • Python操作MySQL基本用法
    • 创建表单类
    • 实现登录功能
    • 博客列表功能实现
    • 添加博客功能实现

数据库设计


创建数据表

需要创建两个数据表

  • users:`用户表,用于存储用户信息
  • articles:博客表,用于存储博客信息

下面以创建users为例:

//如果存在重名的将其删去 DROP TABLE IF EXISTS `articles`; CREATE TABLE `articles` (`id` int NOT NULL AUTO_INCREMENT,`title` varchar(255) DEFAULT NULL,`content` text,`author` varchar(255) DEFAULT NULL,`create_date` datetime DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
  • drop table if exists:一般drop table if exists是数据库里面的,后面接表名如:drop table if exists xxx_book意思就是:如果数据库中存在xxx_book表,就把它从数据库中drop掉。备份sql中一般都有这样的语句,如果是数据库中有这个表,先drop掉,然后create表,然后再进行数据插入。
  • AUTO_INCREMENT:代表值自动增加,只有主键可以添加
  • ENGINE=InnoDB:使用baiinnobd引擎。
  • CHARSET=utf8:数据库默认编码格式为utf8.

### MySQL基本操作

MySQL基本操作

创建数据库操作类

为了复用代码,以及使用的安全性,我们一般会创建一个`myspl_util.py`文件,文件中包含一个`MysqlUtil`类。 import pymysql # 引入pymysql模块 import traceback # 引入python中的traceback模块,跟踪错误 import sys # 引入sys模块class MysqlUtil():def __init__(self):# 初始化方法,连接数据库host = 'localhost' # 主机名user = 'root' # 数据库用户名password = '******' # 数据库密码database = 'notebook' # 数据库名称self.db = pymysql.connect(host=host,user=user,password=password,db=database) # 建立连接self.cursor = self.db.cursor(cursor=pymysql.cursors.DictCursor) # 设置游标,并将游标设置为字典类型def insert(self, sql):'''插入数据库sql:插入数据库的sql语句'''try:# 执行sql语句self.cursor.execute(sql)# 提交到数据库执行self.db.commit()except Exception: # 方法一:捕获所有异常# 如果发生异常,则回滚print("发生异常", Exception)self.db.rollback()finally:# 最终关闭数据库连接self.db.close()def fetchone(self, sql):'''查询数据库:单个结果集fetchone(): 该方法获取下一个查询结果集。结果集是一个对象'''try:# 执行sql语句self.cursor.execute(sql)result = self.cursor.fetchone()except: # 方法二:采用traceback模块查看异常# 输出异常信息traceback.print_exc()# 如果发生异常,则回滚self.db.rollback()finally:# 最终关闭数据库连接self.db.close()return resultdef fetchall(self, sql):'''查询数据库:多个结果集fetchall(): 接收全部的返回结果行.'''try:# 执行sql语句self.cursor.execute(sql)results = self.cursor.fetchall()except: # 方法三:采用sys模块回溯最后的异常# 输出异常信息info = sys.exc_info()print(info[0], ":", info[1])# 如果发生异常,则回滚self.db.rollback()finally:# 最终关闭数据库连接self.db.close()return resultsdef delete(self, sql):'''删除结果集'''try:# 执行sql语句self.cursor.execute(sql)self.db.commit()except: # 把这些异常保存到一个日志文件中,来分析这些异常# 将错误日志输入到目录文件中f = open("\log.txt", 'a')traceback.print_exc(file=f)f.flush()f.close()# 如果发生异常,则回滚self.db.rollback()finally:# 最终关闭数据库连接self.db.close()#以下省略更新功能
  • traceback.print_exc(): 将错误信息在终端输出
  • traceback.print_exc(file=f):可以将错误打印在文本中,f为文件类对象。
  • flush():flush() 方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。
    一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。
  • commit():涉及到更改数据表中的内容,都要在处理之后使用该方法。

exc_info()

exc_info() 方法会将当前的异常信息以元组的形式返回,该元组中包含 3 个元素,分别为 type、value 和 traceback,它们的含义分别是:
  • type:异常类型的名称,它是 BaseException 的子类
  • value:捕获到的异常实例。
  • traceback:是一个 traceback 对象。
  • Python操作MySQL基本用法

    Python操作MySQL

    下边的内容涉及到的Flask知识点较多,可以先看下面这两篇博客。

  • Flask框架基础
  • Flask进阶

  • # 用户登录功能实现

    创建表单类

    from wtforms import Form, StringField, TextAreaField, PasswordField from wtforms.validators import DataRequired,Length,ValidationError from flask_wtf import FlaskForm # 导入我么自己创建的 操作数据库的类 from mysql_util import MysqlUtil# Register Form Class class LoginForm(FlaskForm):username = StringField('用户名',validators=[DataRequired(message='请输入用户名'),Length(min=2, max=25,message='长度在4-25个字符之间')])password = PasswordField('密码',validators = [DataRequired(message='密码不能为空'),Length(min=6,max=20,message='长度在6-20个字符之间'),])def validate_username(self,field):sql = "SELECT * FROM users WHERE username = '%s'" % (field.data) # 根据用户名查找user表中记录db = MysqlUtil() # 实例化数据库操作类result = db.fetchone(sql) # 获取一条记录if not result:raise ValidationError("用户名不存在")

    上述代码中,在Login Form中定义了useame和password字段,它们分别对应着登录页面表单中的用户名和密码。
    此外,还使用validate多段名函数对usermame字段添加自定义验证规则,判断用户名是否存在。

    实现登录功能

    当用户填写登录信息后,如果验证全部通过,需要将登录标识和username写入Session中,为后面判断用户是否登录做准备。此外,还需要在用户访问/logm路由时,判断用户是否已经登录。如果用
    户之前已经登录过,那么则不需要再次登录,而是直接跳转到控制台。

    @app.route('/login', methods=['GET', 'POST']) def login():if "logged_in" in session: # 如果已经登录,则直接跳转到控制台return redirect(url_for("dashboard"))form = LoginForm(request.form) # 实例化表单类if form.validate_on_submit(): # 如果提交表单,并字段验证通过# 从表单中获取字段username = request.form['username']password_candidate = request.form['password'] # 用户填写的密码sql = "SELECT * FROM users WHERE username = '%s'" % (username) # 根据用户名查找user表中记录db = MysqlUtil() # 实例化数据库操作类result = db.fetchone(sql) # 获取一条记录password = result['password'] # 用户注册时候的密码# 对比用户填写的密码和数据库中记录密码是否一致if sha256_crypt.verify(password_candidate, password): # 调用verify方法验证,如果为真,验证通过# 写入sessionsession['logged_in'] = Truesession['username'] = usernameflash('登录成功!', 'success') # 闪存信息return redirect(url_for('dashboard')) # 跳转到控制台else: # 如果密码错误flash('用户名和密码不匹配!', 'danger') # 闪存信息return render_template('login.html',form=form) request.form

    **解释:**通过requset.form可以直接提取请求体中的表单格式的数据, 是一个类字典的对象,所以可以通过request.form['username']获得表单中字段为username对应的数据。

    sha256_crypt.verify()

    解释:verify()方法第一个参数是用户1输入的密码,第二个参数是数据库加密后的密码,如果返回True,则表示密码相同。

    session['logged_in'] = True

    解释:Session对象是一个字典对象,包含会话变量和关联值的键值对。在进行上述设置后,就可以在其余函数中采用session.get('logged_in'),即字典取值的方法判断用户是否已经登录。

    flash('登录成功!', 'success') # 闪存信息

    **解释:**是用来闪现需要显示给用户的内容,上面写入后,可以在需要读取的地方进行读取,如

    {% for message in get_flashed_messages() %}<div class=flash>{{ message }}</div>{% endfor %} return render_template('login.html',form=form)

    **解释:**通过将表单类参数传入模板,在模板中生成一个表单。


    # 用户权限管理功能实现 对于需要用户登录后才能访问的路由,我们可以实现一个装饰器。 def is_logged_in(f):@wraps(f)def wrap(*args, **kwargs):if 'logged_in' in session: # 判断用户是否登录return f(*args, **kwargs) # 如果登录,继续执行被装饰的函数else: # 如果没有登录,提示无权访问flash('无权访问,请先登录', 'danger')return redirect(url_for('login'))return wrap
    • 装饰器的作用: 在不改变原有功能代码的基础上,添加额外的功能,如用户验证等。
    • @wraps(view_func)的作用: 不改变使用装饰器原有函数的结构(如name, doc)
    • 需要导入库:from functools import wraps
    • *args:表示任何多个无名参数,它是一个tuple
    • **kwargs:表示关键字参数,它是一个dict

    # 博客模块设计

    博客列表功能实现

    @app.route('/dashboard') @is_logged_in def dashboard():db = MysqlUtil() # 实例化数据库操作类sql = "SELECT * FROM articles WHERE author = '%s' ORDER BY create_date DESC" % (session['username']) # 根据用户名查找用户笔记信息result = db.fetchall(sql) # 查找所有笔记if result: # 如果笔记存在,赋值给articles变量return render_template('dashboard.html', articles=result)else: # 如果笔记不存在,提示暂无笔记msg = '暂无笔记信息'return render_template('dashboard.html', msg=msg) session['username']

    **解释:**因为在这之前用户已经登录成功,所以可以用上述方法来获取用户名。

    添加博客功能实现

    @app.route('/add_article', methods=['GET', 'POST']) @is_logged_in def add_article():form = ArticleForm(request.form) # 实例化ArticleForm表单类if request.method == 'POST' and form.validate(): # 如果用户提交表单,并且表单验证通过# 获取表单字段内容title = form.title.datacontent = form.content.dataauthor = session['username']create_date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())db = MysqlUtil() # 实例化数据库操作类sql = "INSERT INTO articles(title,content,author,create_date) \VALUES ('%s', '%s', '%s','%s')" % (title,content,author,create_date) # 插入数据的SQL语句db.insert(sql)flash('创建成功', 'success') # 闪存信息return redirect(url_for('dashboard')) # 跳转到控制台return render_template('add_article.html', form=form) # 渲染模板 request.method == 'POST' and form.validate():

    解释:validate是验证数据的意思

    所以from.validate_on_submit()等价于request.method==' post ' and from.validate()


    效果:

    .详细代码可以在评论区留言哦

    • FastAPI ------框架基础
    • python前端学习-----Flask进阶

    总结

    以上是生活随笔为你收集整理的Flask实战----做了一个简易版CSDN的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。