前言
本文简要介绍一个用flask框架和mysql数据库开发的日记管理系统。
一、参数配置
该部分用到了pymysql,flask_sqlalchemy和flask_login三个库,下面对这三个库进行简要的介绍:
pymysql: PyMySQL是一个纯Python编写的MySQL数据库驱动程序。与其他MySQL驱动程序相比,PyMySQL具有轻量级、易于使用和高性能的特点。它提供了与MySQL服务器通信所需的各种功能和方法,使开发人员可以使用Python操作和管理MySQL数据库。
Flask-SQLAlchemy: Flask-SQLAlchemy是基于SQLAlchemy的Flask扩展,提供了集成数据库ORM(对象关系映射)工具的便捷方式。它简化了在Flask应用程序中使用数据库的过程,提供了数据库模型定义、查询和事务处理等功能。Flask-SQLAlchemy还支持多种数据库后端,并且与Flask应用程序无缝集成。
Flask-Login: Flask-Login是一个用于Flask的用户认证管理扩展。它提供了一套简单而灵活的工具,用于处理用户登录、登出、记住我功能以及访问控制等用户认证相关的操作。Flask-Login通过会话和Cookie管理用户状态,使得开发人员可以轻松地添加和管理用户身份验证功能。
该部分中app.config[‘SECRET_KEY’]=os.getenv(‘SECRET_KEY’,‘dev’)旨在从环境中获取密钥,若环境中无密钥,则会采用默认值dev;app.config[‘SQLALCHEMY_DATABASE_URI’]中配置了mysql的相关参数;app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’]=False旨在禁用SQLAlchemy对模型对象的修改跟踪功能。db = SQLAlchemy(app): 这行代码创建了一个名为db的SQLAlchemy实例,并将其绑定到Flask应用程序上。这将使我们能够使用SQLAlchemy来管理数据库模型和执行数据库操作。login_manager = LoginManager(app): 这行代码创建了一个名为login_manager的LoginManager实例,并将其绑定到Flask应用程序上。这将使我们能够使用Flask-Login来处理用户认证和会话管理。@login_manager.user_loader: 这是一个装饰器,用于定义LoginManager的用户加载函数。def load_user(user_id): 这个函数接收一个用户ID作为参数,并返回与该用户ID关联的用户对象。相关代码如下:
from flask import Flask
import os,pymysql
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
pymysql.install_as_MySQLdb()
app = Flask(__name__)
app.config['SECRET_KEY']=os.getenv('SECRET_KEY','dev')
app.config['SQLALCHEMY_DATABASE_URI']='mysql://用户名:数据库密码@域名/数据库名'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False
db=SQLAlchemy(app)
login_manager=LoginManager(app)
@login_manager.user_loader
def load_user(user_id):
from core.models import user-information
user=user-information.query.get(int(user_id))
return user
二、mysql模块
该部分有两个类分别对应mysql中的两张表单用以记录用户信息和日记信息,下文仅以user-information为例介绍相关代码的功能。在类中设置了表单名为user-information,id为主键值用以存放用户信息序号,三个varchar类型的变量user,pwd和sex分别存放用户名,密码和性别信息,以及一个DateTime变量 create_time用以存放创建时间。由于密码直接存放在mysql数据库中缺乏安全性,故我们可以使用werkzeug.security中的generate_password_hash函数完成对密码的加密操作,再使用werkzeug.security中的check_password_hash函数完成对密码的校验。
from pack import db
from flask_login import UserMixin
#记录用户信息的类中需要继承UserMixin类
class user-information(db.Model,UserMixin):
__tablename__='user-information'
id=db.Column(db.Integer,primary_key=True)
user=db.Column(db.String(255))
pwd=db.Column(db.String(255))
sex=db.Column(db.String(255))
create_time=db.Column(db.DateTime)
三、视图函数部分与前端部分
本系统涉及到了注册,登录,登出,创建日记,编辑日记,删除日记等功能,下文仅以创建日记的视图函数和html网页介绍相关代码。
1、视图函数部分
from pack import app,db
from flask import request,flash,redirect,url_for,render_template
from pack.models import user-information
from flask_login import login_required,current_user
#current_user中为当前登录的用户信息
import time
@app.route('/create',methods=['GET','POST'])
@login_required
#@login_required表示该函数只能登录以后被调用
def create():
if request.method=='POST':
content=request.form['content']
priority=request.form['priority']
title=request.form['title']
#获取html表单中提交的内容
new_log=Daily_log(name=current_user.name,content=content,priority=priority,title=title,create_time=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
#创建一个含有表单信息的实例
db.session.add(new_log)
db.session.commit()
#将实例添加进数据库并提交
flash('写入成功')
logs = Daily_log.query.filter(Daily_log.name == current_user.name).all()
#查看数据库中所有与当前登录用户名相同的用户信息
return render_template('history.html',logs=logs)
return render_template('create.html')
2、前端部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>日记本</title>
</head>
<body>
{% for message in get_flashed_messages() %}
<div>{{ message }}</div>
{% endfor %}
<h2>
日记本
</h2>
<nav>
<ul>
<!-- 以下的表单内容旨在为用户创建超链接界面,当用户点击以后会跳转到相应的功能界面 -->
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('create') }}">设置</a></li>
<li><a href="{{ url_for('show') }}">历史</a></li>
<li><a href="{{ url_for('logout') }}">登出</a></li>
{% else %}
<li><a href="{{ url_for('login') }}">登⼊</a></li>
<li><a href="{{ url_for('register') }}">注册</a></li>
{% endif %}
</ul>
</nav>
{% if current_user.is_authenticated %}
{% if logs is defined %}
<form method="post" action="{{url_for('edit', log_id=logs.id)}}">
{% else %}
<form method="post" action="{{url_for('create')}}">
{% endif %}
<label for="title">标题</label>
<textarea cols="20" rows="1" type="text" name="title" autocapitalize="off" id="title" required>{% if logs is defined and logs %}{{ logs.title}}{% endif %}</textarea>
<label for="text">内容</label>
<textarea cols="70" rows="20" type="text" name="content" autocapitalize="off" id="text" required>{% if logs is defined and logs %}{{ logs.content }}{% endif %}</textarea>
<label for="priority">优先级</label>
<select name="priority" id="priority">
{% if logs is defined %}
{% if logs.priority=='高' %}
<option value="高" selected="selected">高</option>
<option value="中" >中</option>
<option value="低" >低</option>
{% elif logs.priority=='中' %}
<option value="高" >高</option>
<option value="中" selected="selected">中</option>
<option value="低" >低</option>
{% else %}
<option value="高" >高</option>
<option value="中" >中</option>
<option value="低" selected="selected">低</option>
{% endif %}
{% else %}
<option value="高" >高</option>
<option value="中" >中</option>
<option value="低" >低</option>
{% endif %}
</select>
{% if logs is defined %}
<input type="submit" name="submit" value="更新日记">
{% else %}
<input type="submit" name="submit" value="新建日记">
{% endif %}
</form>
</form>
</body>
</html>